Пустое содержимое интерфейса в Go
Пустой указатель, положенный в интерфейс, не делает сам интерфейс пустым. Внутри остается запись о типе указателя, даже если адрес равен нулю. Сравнение с пустым интерфейсом тогда дает ложь, хотя содержимое по сути ничего нет.
Возьмем нулевой указатель на пользователя и запишем его в интерфейс с методом печати:
package main
import "fmt"
type Printer interface {
Print()
}
type User struct {
Name string
}
func (u *User) Print() {
if u == nil {
fmt.Println("empty user")
return
}
fmt.Println(u.Name)
}
func main() {
var u *User = nil
var p Printer = u
fmt.Println(p == nil)
}
На экране false. В p лежит
тип *User и нулевой адрес, поэтому
p == nil не выполняется. Это частая
ловушка при проверке «пусто ли значение».
Сравнивать нужно осмысленно, зная, что
внутри интерфейса хранится тип:
package main
import "fmt"
type Printer interface {
Print()
}
func main() {
var p Printer = nil
fmt.Println(p == nil)
}
Здесь на экране true: переменная
интерфейса не получила ни тип, ни значение.
Только такое сравнение означает полностью
пустой интерфейс.
Повторите первый пример урока с *User
и выведите результат сравнения с пустым
интерфейсом.
Дан следующий код:
package main
type Worker interface {
Work()
}
type Task struct{}
func (t *Task) Work() {}
Запишите var t *Task = nil в
Worker и скажите, будет ли сравнение
с пустым интерфейсом истинным.
Скажите, чем отличается var p Printer = nil
от присваивания нулевого указателя конкретного
типа в Printer.