title | description |
---|---|
Nil errors that are non-nil errors |
Difference between nil interface value and interface holding a nil value |
Consider the following code:
package main
import "fmt"
type E struct {}
func (*E) Error() string { return "error" }
func f() error {
var err *E = nil
return err
}
func main() {
if err := f(); err != nil {
panic(err)
}
fmt.Println("success")
}
You can easily check that although f() error
always returns nil
, f() != nil
so this code panics.
An interface in Go is a tuple of (type, value). In the following code:
var err error
err
has nil
value since we didn't assign anything to it, but in:
var (
specific *E
err error = specific
)
We're setting the err's value to a (*E, nil)
tuple, there's a type, but it doesn't point to any value.
You can check that out in the following example:
package main
import "fmt"
type Printer interface{ Print() }
type StringPrinter string
func (s *StringPrinter) Print() {
if s == nil {
fmt.Println("nil value")
return
}
fmt.Println(*s)
}
func main() {
var (
sp *StringPrinter
printer Printer = sp
)
printer.Print()
}
Since printer already has a type, we can already call pointer receiver functions on it, although it's value is nil. Obviously you can't do that if you don't specify the type, because there's nowhere to call.