Why does calling hello() on a nil *gopher pointer succeed instead of panicking?
Read the snippet below. A pointer-receiver method hello is called on a nil *gopher pointer.
Determine what the program prints, and explain why calling hello() on a nil receiver succeeds instead of panicking.
type gopher struct{ name string }
func (g *gopher) hello() { fmt.Println("hello works") }
func main() {
var g *gopher // nil
g.hello()
}
Predict the output.
A pointer-receiver method is just a function taking the pointer as its first argument, so calling it on a nil pointer is legal as long as the body never dereferences that pointer. hello only prints a constant and never touches g.name, so it runs fine. Accessing g.name would panic with a nil dereference.
- ✗Assuming any method call on a
nilpointer panics at the call site - ✗Thinking Go allocates a zero value for a
nilreceiver - ✗Forgetting the panic happens only when the body dereferences the
nilpointer (e.g.g.name)
- →What exact runtime error appears if
helloreadsg.nameon thenilreceiver? - →How do some standard types (like a
nil*Tree) deliberately rely on nil-receiver methods?
What does this code print?
type gopher struct{ name string }
func (g *gopher) hello() { fmt.Println("hello works") }
func main() {
var g *gopher // nil
g.hello()
}
Output
hello works
Why the call succeeds
A pointer-receiver method func (g *gopher) hello() is, under the hood, an ordinary function hello(g *gopher). The call g.hello() simply passes g (here nil) as the first argument.
That is legal: you may always pass a nil pointer to a function. The panic comes not from the call but from a dereference. hello only prints a constant and never touches g.name, so nothing is dereferenced — the method runs.
⚠️ Had the body read a field through the nil pointer:
func (g *gopher) hello() { fmt.Println(g.name) } // g.name on nil
// panic: runtime error: invalid memory address or nil pointer dereference
This is sometimes relied on deliberately: e.g. methods on a nil *Tree, where nil means "empty tree".