Пустой интерфейс interface{
Пустой интерфейс interface{} (или просто пустой интерфейс) — это особый тип в Go, который объявляет ноль методов. Это означает, что любой тип в Go удовлетворяет этому интерфейсу, поскольку для его реализации не требуется реализовывать ни одного метода. Следовательно, переменная типа interface{} может хранить значение абсолютно любого типа: число, строку, структуру, слайс, другую переменную интерфейса или даже сам nil.
Пустой интерфейс часто используется в ситуациях, когда тип данных неизвестен на этапе компиляции, например, при работе с функциями, принимающими аргументы разных типов, или при хранении разнородных значений в коллекциях. Однако следует помнить, что для работы с конкретным значением, хранящимся в пустом интерфейсе, необходимо использовать утверждение типа (type assertion) или переключатель типов (type switch), чтобы получить доступ к его реальному типу и методам.
Синтаксис
var anyVar interface{}
anyVar = valueOfAnyType
Объявление переменной типа interface{} и присвоение ей значения любого типа.
Пример
Давайте объявим переменную типа interface{} и присвоим ей значения разных типов:
package main
import "fmt"
func main() {
var anyVar interface{}
anyVar = 123
fmt.Println(anyVar)
anyVar = "hello, world"
fmt.Println(anyVar)
anyVar = true
fmt.Println(anyVar)
anyVar = []int{1, 2, 3}
fmt.Println(anyVar)
}
Результат выполнения кода:
123
"hello, world"
true
[1 2 3]
Как видно из примера, переменная anyVar без проблем хранит значения типа int, string, bool и даже слайс []int.
Пример
Пустой интерфейс часто используется для создания функций, которые могут принимать аргументы любого типа. Например, функция печати с дополнительной информацией:
package main
import "fmt"
func printValue(v interface{}) {
fmt.Printf("Type: %T, Value: %v\n", v, v)
}
func main() {
printValue(42)
printValue("Go")
printValue(3.14)
printValue([]string{"a", "b", "c"})
}
Результат выполнения кода:
"Type: int, Value: 42"
"Type: string, Value: Go"
"Type: float64, Value: 3.14"
"Type: []string, Value: [a b c]"
Функция printValue принимает параметр типа interface{} и с помощью fmt.Printf выводит тип и значение переданного аргумента.
Пример
Пустой интерфейс можно использовать для хранения элементов разных типов в одной коллекции, например, в слайсе:
package main
import "fmt"
func main() {
mixed := []interface{}{42, "text", 3.14, true, []int{1, 2, 3}}
for _, val := range mixed {
fmt.Printf("Value: %v, Type: %T\n", val, val)
}
}
Результат выполнения кода:
"Value: 42, Type: int"
"Value: text, Type: string"
"Value: 3.14, Type: float64"
"Value: true, Type: bool"
"Value: [1 2 3], Type: []int"
Слайс mixed может содержать одновременно элементы разных типов благодаря использованию типа элемента interface{}. При итерации по слайсу мы получаем доступ и к значению, и к его динамическому типу.
Смотрите также
-
тип
any— псевдоним дляinterface{}, введенный в Go 1.18,
который делает код более читаемым -
операцию
утверждение типа,
которая позволяет извлечь значение конкретного типа из интерфейса -
конструкцию
переключатель типов,
которая упрощает проверку типа значения, хранящегося в интерфейсе -
понятие
nil-интерфейс,
которое описывает состояние интерфейсной переменной без присвоенного значения