Все вопросы

30 Свои типы

Почему интерфейс с nil внутри не равен nil?

Интерфейс равен nil, только когда в нём нет ни типа, ни значения. Если положить туда типизированный nil, например (*Cat)(nil), тип уже есть. Сравнение s == nil даёт false, хотя указатель внутри нулевой.

Отсюда классическая ошибка: функция возвращает error как return (*MyError)(nil) или возвращает конкретный указатель из функции с результатом error. Вызывающий видит ненулевой error.

Возвращай буквальный nil, когда ошибки нет: return nil, а не типизированную пустую переменную.

Пример

Go

пустой интерфейс и интерфейс с 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)
}