Go stores interfaces as a pair of values: a type, and the actual value, and will only be equal to nil
if both are.
As a consequence, a nil
value stored in an interface variable, but as a pointer to another type, will not pass the == nil
test. To illustrate:
type myInterface interface {
sayHi()
}
type myName string
func (n myName) sayHi() {
fmt.Println("Hi there! My name is " + n)
}
func main() {
test1 := myName("Camilo")
run("test 1", test1)
var test2 myInterface
run("test 2", test2)
var test3 *myName
run("test 3", test3)
}
func run(label string, a myInterface) {
fmt.Println("======== " + label + " ========")
fmt.Println("value:", reflect.ValueOf(a))
fmt.Println("type: ", reflect.TypeOf(a))
if a == nil {
fmt.Println("I'm nil")
} else if reflect.ValueOf(a).Kind() == reflect.Ptr && reflect.ValueOf(a).IsNil() {
fmt.Println("I'm nil (weird case!)")
} else {
a.sayHi()
}
}
sayHi()
}
type myName string
func (n myName) sayHi() {
fmt.Println("Hi there! My name is " + n)
}
func main() {
test1 := myName("Camilo")
run("test 1", test1)
var test2 myInterface
run("test 2", test2)
var test3 *myName
run("test 3", test3)
}
func run(label string, a myInterface) {
fmt.Println("======== " + label + " ========")
fmt.Println("value:", reflect.ValueOf(a))
fmt.Println("type: ", reflect.TypeOf(a))
if a == nil {
fmt.Println("I'm nil")
} else if reflect.ValueOf(a).Kind() == reflect.Ptr && reflect.ValueOf(a).IsNil() {
fmt.Println("I'm nil (weird case!)")
} else {
a.sayHi()
}
}