Code
package main
import "fmt"
type I interface {
M()
}
type T struct {
S string
}
func (t *T) M() {
if t == nil {
fmt.Println("<nil>")
return
}
fmt.Println(t.S)
}
func main() {
var i I
nullDescribe(i)
var t *T
fmt.Printf("t == nil: %v\n", t == nil)
nullDescribe(t)
i = t
describe(i)
i.M()
describe(t)
t.M()
i = &T{"hello"}
describe(i)
i.M()
}
func describe(i I) {
fmt.Printf("(%v, %T)\n", i, i)
}
func nullDescribe(i I) {
fmt.Printf("nullDescribe: ")
if i == nil {
fmt.Printf("...nil\n")
} else {
fmt.Printf("...not nil\n")
}
}
Will return
nullDescribe: ...nil
t == nil: true
nullDescribe: ...not nil
(<nil>, *main.T)
<nil>
(<nil>, *main.T)
<nil>
(&{hello}, *main.T)
hello
Why ?
Yes, t has default value nil, but interface in nullDescribe() holds its nil value so interface is not nil.
Links
http://www.golangprograms.com/how-to-check-pointer-or-interface-is-nil.html
https://github.com/dmitryrpm/maxima-tests/blob/master/test3.go
https://yourbasic.org/golang/default-zero-value/
https://medium.com/golangspec/interfaces-in-go-part-i-4ae53a97479c pretty good explaination
https://medium.com/golangspec/interfaces-in-go-part-ii-d5057ffdb0a6