-
Notifications
You must be signed in to change notification settings - Fork 18.7k
Description
A common error for people new to Go is misunderstanding that a interface that is not nil can contain a nil pointer. This is one of the most commonly cited entries in the Go FAQ: https://golang.org/doc/faq#nil_error. A quick search shows at least 24 threads on golang-nuts discussing this, even though it is already in the FAQ.
It is not new to observe that one of the causes of this common mistake is that nil is overloaded. Since changing that would not be backwards compatible, I propose the following changes.
-
We add six new predefined identifiers:
nilptr,nilinterface,nilslice,nilchan,nilfunc,nilmap. These new identifiers are untyped constants that only resolve to a certain kind, much as1.1is an untyped constant that only resolves to afloatorcomplextype.nilptrmay be used as the zero value for any pointer type,nilinterfacemay be used as the zero value for any interface type, and so forth. An attempt to use, for example,nilptrin an assignment or comparison with a variable or value that is not a pointer type is invalid. -
We add a vet check that warns about any comparison of a value of any type with plain
nil. We encourage people to changex == niltox == nilinterfaceorx == nilptror whatever is appropriate. Since initially this vet check will trigger all the time, we can not turn it on when runninggo test. It could be on by default when runninggo vet. -
At this point people who run
go vetwill no longer make the common mistake. Ifvis a value of interface type, then writingv == nilptrwill be a compilation error. Writingv == nilinterfacewill not cause people to erroneously think that this is testing whethervcontains anilpointer. -
In some later release, we turn on the vet check when running
go test. -
If we are ever willing to make a backward incompatible change, we can make
v == nila compilation error rather than simply being a vet error.
Something to consider is that one could imagine permitting v == nilptr when v has an interface type, and having this be true if v is not nilinterface, if v holds a value of pointer type, and if the pointer value is nilptr. I don't know that this is a good idea, and I'm not proposing it. I'm only proposing the above.