вторник, 18 февраля 2020 г.

Почему nil может быть не равен nil в Golang

Почему в этом примере nil не равен nil?

func Foo() error {
    var err *os.PathError = nil
    // …
    return err
}

func main() {
    err := Foo()
    fmt.Println(err)        // <nil>
    fmt.Println(err == nil) // false
}

Ответ

Значение интерфейса равно nil, только если его значение и динамический тип равны nil. В приведенном выше примере Foo() возвращает [nil, *os.PathError], и мы сравниваем его с [nil, nil].

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

…
fmt.Println(err == (*os.PathError)(nil)) // true
…

Лучший подход

Чтобы избежать этой проблемы, используйте вместо этого переменную типа error, например именованное возвращаемое значение.

func Foo() (err error) {
    // …
    // err не назначен и имеет нулевое значение [nil, nil]
    return 
}

func main() {
    err := Foo()
    fmt.Println(err)        // <nil>
    fmt.Println(err == nil) // true
}

Рекомендация. Используйте встроенный тип интерфейса error, а не конкретный тип, для хранения и возврата значений ошибок.


Читайте также:


Комментариев нет:

Отправить комментарий