Что такое nil-интерфейс в Go и в чем его особенность?

Ответ

Интерфейс в Go внутренне представляет собой пару (type, value) — конкретный тип и значение этого типа.

Nil-интерфейс — это интерфейс, у которого и тип, и значение равны nil. То есть, пара выглядит как (nil, nil).

var i interface{} // Тип = nil, Значение = nil
fmt.Println(i == nil) // Выведет: true

Особенность и частая ошибка заключается в интерфейсе, который содержит nil-указатель на конкретный тип. Такой интерфейс не является nil-интерфейсом, потому что его компонент type не равен nil.

var p *int          // p - это nil-указатель на int
var i interface{} = p // Тип = *int, Значение = nil

// Проверка i == nil вернет false, так как тип в интерфейсе установлен (*int)
fmt.Println(i == nil) // Выведет: false

Это критически важно при обработке ошибок. Если функция возвращает ошибку типа *CustomError, а вы возвращаете nil этого типа, то результирующий интерфейс error не будет равен nil.

Правильный способ проверки:
Для безопасной проверки нужно использовать рефлексию или приведение типов.

if i != nil && !reflect.ValueOf(i).IsNil() {
    // Интерфейс не nil и содержит не nil значение
}