30 Свои типы
Почему интерфейс с nil внутри не равен nil?
Ответ
Интерфейс равен nil, только когда в нём нет ни типа, ни значения. Если положить туда типизированный nil, например (*Cat)(nil), тип уже есть. Сравнение s == nil даёт false, хотя указатель внутри нулевой.
Подробнее
Отсюда классическая ошибка: функция возвращает error как return (*MyError)(nil) или возвращает конкретный указатель из функции с результатом error. Вызывающий видит ненулевой error.
Возвращай буквальный nil, когда ошибки нет: return nil, а не типизированную пустую переменную.
package main
import "fmt"
type Speaker interface {
Speak() string
}
type Cat struct{}
func (c *Cat) Speak() string { return "мяу" }
func main() {
var s Speaker
fmt.Println("пустой:", s == nil)
var c *Cat
s = c
fmt.Println("внутри nil-указатель:", s == nil)
fmt.Printf("динамический тип: %T\n", s)
}