静态检查Nil接口值?

Let's say we have the following:

type I interface {
    M()
}

func main() {
    var i I
    i.M()
}

Why does Go not do some static analysis at compile type to check that the underlying value of the interface is nil and throw a compile time error? Instead we end up throwing a runtime exception at i.M()

==================================================================

Output:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0xffffffff addr=0x0 pc=0x2004d]

goroutine 1 [running]:
panic(0x13f480, 0x1040a038)
    /usr/local/go/src/runtime/panic.go:481 +0x700
main.main()
    /tmp/sandbox469152264/main.go:12 +0x4d

Why does Go not do some static analysis at compile type to check that the underlying value of the interface is nil and throw a compile time error?

The zero value for interface is nil, and it is no more detected at compile time than any other nil value.
From the FAQ:

Under the covers, interfaces are implemented as two elements, a type and a value.

  • The value, called the interface's dynamic value, is an arbitrary concrete value and
  • the type is that of the value.

An interface value is nil only if the inner value and type are both unset, (nil, nil).
In particular, a nil interface will always hold a nil type.


This thread adds, regarding the nil value (runtime):

The basic answer is to never store something in an interface if you don't expect the methods to be called on it.
The language may allow it, but that violates the semantics of the interface.

To expound, a nil value should usually not be stored in an interface unless it is of a type that has explicitly handled that case in its pointer-valued methods and has no value-receiver methods.