Ответ
Для определения конкретного типа значения, которое хранится в пустом интерфейсе interface{}
(или его псевдониме any
), в Go есть два основных идиоматичных способа: утверждение типа (type assertion) и переключатель типов (type switch).
1. Утверждение типа (Type Assertion)
Это способ проверить, содержит ли переменная интерфейса значение определённого типа, и извлечь его. Безопасная форма возвращает два значения:
value
: значение, приведённое к указанному типу.ok
: булево значение,true
если преобразование успешно, иfalse
в противном случае.
Использование формы с одним возвращаемым значением (val.(string)
) вызовет панику, если тип не совпадёт.
var i interface{} = "hello"
// Безопасное утверждение типа
if s, ok := i.(string); ok {
fmt.Printf("Значение '%s' является строкойn", s)
}
2. Переключатель типов (Type Switch)
Это наиболее удобный способ, если нужно проверить значение на соответствие нескольким разным типам.
func checkType(i any) {
switch v := i.(type) {
case int:
fmt.Printf("Это целое число: %dn", v)
case string:
fmt.Printf("Это строка: %sn", v)
case bool:
fmt.Printf("Это булево значение: %tn", v)
default:
fmt.Printf("Неизвестный тип: %T со значением %vn", v, v)
}
}
checkType(42)
checkType("hello")
Рефлексия (reflect
): В качестве альтернативы можно использовать пакет reflect
(reflect.TypeOf(i)
), но это более медленный и сложный подход. Его стоит применять только в тех случаях, когда типы неизвестны на этапе компиляции.