Nil-интерфейс

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

Синтаксис

Объявление интерфейсной переменной без присвоения значения создает nil-интерфейс. Такой интерфейс можно проверить на равенство с nil.

govar i interface{}
if i == nil {
  fmt.Println("i is nil")
}

Пример

Создадим nil-интерфейс и проверим его на nil:

gopackage main

import "fmt"

func main() {
  var i interface{}
  fmt.Printf("i == nil: %v\n", i == nil)
  fmt.Printf("i: %v\n", i)
}

Результат выполнения кода:

go"i == nil: true"
"i: <nil>"

Пример

Ниже показано, что интерфейс, содержащий указатель на nil, не является nil-интерфейсом:

gopackage main

import "fmt"

func main() {
  var p *int = nil
  var i interface{} = p
  fmt.Printf("i == nil: %v\n", i == nil)
  fmt.Printf("i: %v\n", i)
}

Результат выполнения кода:

go"i == nil: false"
"i: <nil>"

Пример

Функция, возвращающая error, может вернуть nil-интерфейс только если возвращает явный nil:

gopackage main

import (
  "errors"
  "fmt"
)

func getError(flag bool) error {
  if flag {
    return errors.New("some error")
  }
  return nil
}

func main() {
  err := getError(false)
  fmt.Printf("err == nil: %v\n", err == nil)
}

Результат выполнения кода:

go"err == nil: true"

Смотрите также

  • функцию interface,
    которая описывает базовый синтаксис и назначение интерфейсов
  • функцию empty-interface,
    которая может хранить значения любого типа
  • функцию type-assertion,
    которая извлекает значение конкретного типа из интерфейса
  • функцию nil-pointer,
    которая сравнивает интерфейс с нулевым указателем