Ответ
В Go для проверки конкретного типа, скрытого за интерфейсом, используются две основные конструкции: утверждение типа (type assertion) и переключатель типов (type switch).
1. Утверждение типа (Type Assertion)
Этот механизм используется, когда вы ожидаете, что интерфейс содержит значение определённого конкретного типа.
Синтаксис value, ok := i.(T)
является наиболее безопасным и идиоматичным. Он возвращает два значения:
value
: значение, приведённое к типуT
, если утверждение успешно.ok
: булево значение,true
при успехе иfalse
в противном случае.
package main
import "fmt"
func main() {
var i interface{} = "hello world"
// Безопасная проверка
s, ok := i.(string)
if ok {
fmt.Printf("Значение: '%s', тип: stringn", s)
} else {
fmt.Println("Тип не является string")
}
// Пример с неверным типом
f, ok := i.(float64)
if !ok {
fmt.Printf("Переменная i не содержит тип float64. f = %vn", f) // f будет нулевым значением для float64
}
// Утверждение типа с одним значением (может вызвать панику!)
// Используйте только когда на 100% уверены в типе.
// s = i.(string) // Успешно
// i = 5
// s = i.(string) // паника: interface conversion: interface {} is int, not string
}
2. Переключатель типов (Type Switch)
Это более гибкая конструкция, которая позволяет элегантно обработать несколько возможных типов в одной switch
инструкции.
package main
import "fmt"
func checkType(i interface{}) {
switch v := i.(type) { // Специальный синтаксис i.(type)
case string:
fmt.Printf("Это строка со значением: %sn", v)
case int:
fmt.Printf("Это целое число со значением: %dn", v)
case bool:
fmt.Printf("Это булево значение: %tn", v)
default:
fmt.Printf("Неизвестный тип: %T со значением: %vn", v, v)
}
}
func main() {
checkType("Go")
checkType(42)
checkType(true)
checkType(12.34)
}
Когда что использовать?
- Type Assertion: Когда вам нужно проверить соответствие одному конкретному типу.
- Type Switch: Когда вам нужно обработать несколько разных возможных типов.