Ответ
В Go нет прямого аналога примитива union
из таких языков, как C/C++. Вместо этого для хранения значений разных типов используется пустой интерфейс any
(в версиях до Go 1.18 — interface{}
).
any
может содержать значение любого типа. Чтобы работать с конкретным типом, используется механизм проверки типа (type assertion) или switch
по типу.
Пример с switch
:
func printValue(v any) {
switch val := v.(type) {
case int:
fmt.Printf("Это целое число: %dn", val)
case string:
fmt.Printf("Это строка: %sn", val)
case bool:
fmt.Printf("Это булево значение: %tn", val)
default:
fmt.Println("Неизвестный тип")
}
}
Основные сценарии использования:
- Обработка данных неизвестного типа: Например, при декодировании JSON или данных из базы, где поле может иметь разный тип.
- Создание гетерогенных коллекций: Слайсы или мапы, которые могут хранить элементы разных типов.
- Реализация полиморфного поведения без строгой привязки к общему интерфейсу.
Важно: Чрезмерное использование any
снижает типобезопасность и читаемость кода, так как проверки типов переносятся из времени компиляции во время выполнения. С появлением дженериков в Go 1.18 для создания типобезопасных функций и структур данных, работающих с разными типами, предпочтительнее использовать именно их.