Calls
…
Calling a
nil
function value causes a run-time panic.
So, calling a nil
function causes a panic. Sensible enough. But when would you ever run across a nil
function?
Let’s look at some examples.
This is probably the most obvious example, and perhaps one that popped to your mind:
var fn func(int) // fn is of type func(int), but uninitialized, so nil
fn(3) // run-time panic
But let’s consider another example, which can be a bit more confusing.
type Fooer interface {
Foo()
}
type Wrapper struct {
Fooer
}
w := &Wrapper{}
f := w.Foo
f() // run-time panic
Okay, that’s a lot of set-up for a run-time panic on a nil function. What’s actually going on?
Well first, I created an interface called Fooer
, then I embedded that interface in a struct called Wrapper
. This can be a useful technique in some cases, but it assumes that you’ll be setting the Fooer
field of the struct to something that implements the interface. In contract, when I defined w := &Wrapper{}
, I did not set the Fooer
field, so it gets a nil value.
Then if I call w.Foo()
, or set function variable to its value (i.e. f := w.Foo
), I end up with a nil method or function respectively, and thus a run-time panic.
Quotes from The Go Programming Language Specification Version of August 2, 2023