Программа напечатает oops. При i=4 err внутри foo равен nil как *MyError, но возврат упаковывает его в интерфейс error с ненулевым динамическим типом.
Как правильно сравнивать error с nil в Go
Программа напечатает oops. При i=4 err внутри foo равен nil как *MyError, но возврат упаковывает его в интерфейс error с ненулевым динамическим типом.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Определите, какой вывод будет у следующей программы при её запуске.
package main
import "fmt"
type MyError struct {
data string
}
func (e *MyError) Error() string {
return e.data
}
func main() {
err := foo(4)
if err != nil {
fmt.Println("oops")
} else {
fmt.Println("ok")
}
}
func foo(i int) error {
var err *MyError
if i > 5 {
err = &MyError{data: "i > 5"}
}
return err
}
Ответ
Программа напечатает oops. При i=4 err внутри foo равен nil как *MyError, но возврат упаковывает его в интерфейс error с ненулевым динамическим типом.
Проверка err!=nil поэтому истинна. Метод Error не вызывается: main печатает только строку oops, так что разыменования nil здесь нет. Исправьте foo: if i > 5 { return &MyError{data: "i > 5"} }; return nil. Альтернатива — объявить локальную переменную именно типа error и оставлять её nil при успехе.