Проверка типа type assertion

Проверка типа (type assertion) в Go используется для извлечения конкретного значения из переменной интерфейсного типа. Она позволяет получить значение, хранящееся в интерфейсе, и проверить, соответствует ли оно определенному типу. Первым параметром выступает переменная интерфейсного типа, а вторым — целевой тип, к которому мы пытаемся привести интерфейс.

Операция проверки типа возвращает извлеченное значение и булев флаг, указывающий на успешность приведения. Если не использовать второй возвращаемый параметр, то в случае неуспешного приведения возникнет паника.

Синтаксис

govalue, ok := interfaceVar.(TargetType)

Где interfaceVar — переменная интерфейсного типа, TargetType — конкретный тип, к которому мы пытаемся привести, value — извлеченное значение, ok — булев флаг (true если приведение успешно).

Пример

Рассмотрим простой пример успешной проверки типа с использованием формы с проверкой (comma-ok idiom):

gopackage main

import "fmt"

func main() {
  var i interface{} = "abcde"

  if s, ok := i.(string); ok {
    fmt.Println("String value:", s)
  } else {
    fmt.Println("Not a string")
  }
}

Результат выполнения кода:

go"String value: abcde"

Пример

Теперь рассмотрим случай, когда приведение типа не удается. В этом случае второй возвращаемый параметр (ok) будет равен false, а значение будет нулевым для целевого типа:

gopackage main

import "fmt"

func main() {
  var i interface{} = 12345

  if s, ok := i.(string); ok {
    fmt.Println("String value:", s)
  } else {
    fmt.Println("Not a string")
  }
}

Результат выполнения кода:

go"Not a string"

Пример

Если не использовать второй возвращаемый параметр (форму без проверки), то в случае неуспешного приведения возникает паника. Это может быть полезно, когда вы точно уверены в типе:

gopackage main

import "fmt"

func main() {
  var i interface{} = "abcde"

  s := i.(string)
  fmt.Println("String value:", s)
}

Результат выполнения кода:

go"String value: abcde"

Пример

Пример, который вызовет панику, потому что мы пытаемся привести int к string:

gopackage main

func main() {
  var i interface{} = 12345

  _ = i.(string) // panic: interface conversion: interface {} is int, not string
}

Результат выполнения кода:

go"panic: interface conversion: interface {} is int, not string"

Смотрите также

  • статью comma-ok idiom,
    которая описывает идиому безопасного приведения типов
  • статью type switch,
    которая позволяет выполнять действия в зависимости от типа интерфейса
  • статью пустой интерфейс,
    который может хранить значения любого типа
  • статью nil-интерфейс,
    которая рассматривает особенности работы с нулевыми интерфейсами