Nil interfaces
An interface value is only nil when both its dynamic type and dynamic value are nil.
Canonical guidance
- an interface is
nilonly if it holds no dynamic type and no dynamic value - a typed nil inside an interface is not the same as a nil interface
- be careful returning concrete pointer types as
error
Use when
- debugging surprising
err != nil - reviewing interface-heavy APIs
- explaining nil behavior in Go
Avoid
- assuming a nil pointer assigned to an interface makes the interface nil
- returning typed nil errors accidentally
Preferred pattern
if err == nil {
return nil
}
return err
Anti-pattern
var e *MyError = nil
return e
- if returned as
error, the interface now has dynamic type*MyError
Explanation: This anti-pattern is common because a nil pointer looks nil in the debugger, but once wrapped in an interface it can change control flow unexpectedly.
Why
- interface values are represented as type plus value
- nil confusion here is a common correctness and API bug
Sources
- Go Data Structures: Interfaces - Russ Cox
- Why is my nil error value not equal to nil? - Go Team