What does this print? (nil interface vs interface holding a nil pointer)
Question 79MediumGo 1.22 to 1.25
package main
import "fmt"
type T struct{}
func main() {
var p *T = nil
var i any = p
var j any
fmt.Println(p == nil) // ?
fmt.Println(i == nil) // ?
fmt.Println(j == nil) // ?
fmt.Printf("%T %v\n", i, i)
}
Output:
true
false
true
*main.T <nil>
i has dynamic type *T and a dynamic value of nil. The type word is set, so i != nil. An interface equals nil only when its type and value words are both nil. j was never assigned, so both words are nil.
To test whether the value inside is nil, use a type assertion (v, ok := i.(*T); ok && v == nil) or reflection (reflect.ValueOf(i).IsNil(), which panics for kinds that cannot be nil). The interviewer is checking that you can explain this from the two-word representation instead of just remembering the rule.
More on Interfaces, Methods & Embedding
- Q77How is an interface value represented at runtime? What is the difference between
ifaceandeface? - Q78What is an itab, when is it built, and what does a method call through an interface cost?
- Q80Why does this function return a non-nil error even when nothing failed? How do you fix it?
- Q81Explain method sets. Why does
*Tsatisfy an interface whenTdoes not? - Q82Why doesn't
m["k"].Inc()compile whenInchas a pointer receiver? What other values are not addressable? - Q83How do you decide between value and pointer receivers?