Почему в этом примере 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, а не конкретный тип, для хранения и возврата значений ошибок.
Читайте также:
- Тип, значение и равенство интерфейсов в Golang
- Go FAQ: Почему nil значение ошибки не равно nil?
- Golang puzzlers: возврат ошибки
Комментариев нет:
Отправить комментарий