Nil is not nil
yourbasic.org/golang
Why is nil not equal to nil in this example?
func Foo() error {
var err *os.PathError = nil
// …
return err
}
func main() {
err := Foo()
fmt.Println(err) // <nil>
fmt.Println(err == nil) // false
}
Answer
An interface value is equal to nil
only if both its value and dynamic type are nil
.
In the example above, Foo()
returns [nil, *os.PathError]
and we compare it with [nil, nil]
.
You can think of the interface value nil
as typed, and nil
without type doesn’t equal nil
with type.
If we convert nil
to the correct type, the values are indeed equal.
…
fmt.Println(err == (*os.PathError)(nil)) // true
…
A better approach
To avoid this problem use a variable of type error
instead, for example a [named return value](/golang/named-return-values-parameters/).
func Foo() (err error) {
// …
return // err is unassigned and has zero value [nil, nil]
}
func main() {
err := Foo()
fmt.Println(err) // <nil>
fmt.Println(err == nil) // true
}
Best practice: Use the built-in
error
interface type, rather than a concrete type, to store and return error values.
See Interfaces in 5 easy steps for an extensive guide to interfaces in Go.