This is, it turns out, a Frequently Asked Question about Go, and the short answer is that interface comparisons compare the type and the value, and (*Goof)(nil)
and error(nil)
have different types.
Since if err != nil
is standard, you want a return value that'll work with it. You could declare var err error
instead of var g *Goof
: err
's zero value is conveniently error(nil)
Or, if your func returns an error
, return nil
will return what you want.
For more background, here's the start of the FAQ's answer:
Under the covers, interfaces are implemented as two elements, a type and a value. The value, called the interface's dynamic value, is an arbitrary concrete value and the type is that of the value. For the int
value 3
, an interface value contains, schematically, (int, 3)
.
An interface value is nil
only if the inner value and type are both unset, (nil, nil)
. In particular, a nil
interface will always hold a nil
type. If we store a pointer of type *int
inside an interface value, the inner type will be *int
regardless of the value of the pointer: (*int, nil)
. Such an interface value will therefore be non-nil
even when the pointer inside is nil
.
And ==
is strictly checking if the types are identical, not if a type (*Goof
) implements an interface (error
). Check out the original for more.
If it helps clarify, this doesn't only happen with nil
: in this example, the data underlying the x
and y
variables is obviously 3
, but they have different types. When you put x
and y
into interface{}
s, they compare as unequal:
package main
import "fmt"
type Bob int
func main() {
var x int = 3
var y Bob = 3
var ix, iy interface{} = x, y
fmt.Println(ix == iy)
}