Когда интерфейс в Go равен nil?

Ответ

Интерфейс в Go равен nil только в том случае, когда и его динамический тип, и динамическое значение равны nil.

Интерфейсная переменная имеет два компонента:

  1. Тип — конкретный тип данных, который в ней хранится.
  2. Значение — само значение этого типа.

Если в интерфейс положить nil-указатель на какой-либо тип, интерфейс не будет равен nil, так как его компонент типа будет установлен.

Классический пример-ловушка:

package main

import "fmt"

func main() {
    // 1. Полностью nil-интерфейс
    var i interface{}
    fmt.Printf("Тип: %T, Значение: %v, Равен nil: %tn", i, i, i == nil)
    // Вывод: Тип: <nil>, Значение: <nil>, Равен nil: true

    // 2. Интерфейс с nil-указателем внутри
    var p *int = nil
    i = p
    fmt.Printf("Тип: %T, Значение: %v, Равен nil: %tn", i, i, i == nil)
    // Вывод: Тип: *int, Значение: <nil>, Равен nil: false
}

Вывод: nil-интерфейс и интерфейс, содержащий nil-значение, — это разные вещи. Прямое сравнение if myInterface == nil может привести к ошибкам, если вы не ожидаете такого поведения.