A different way to state your argument is that nil is overloaded in
Go. Your argument is essentially identical to saying suppose you have
an integer r:
type MyIntegerType int
var r MyIntegerType
and a bunch of code that tests whether r is 0 or not
if r != 0 {
r.doSomething()
}
Then you change r to an interface type, and now the meaning of r != 0
has subtly changed. The code still compiles, but now it means
something different. r != 0 will be true even if the value of r
actually is 0, because in `r != 0` the `0` will be given type `int`,
but `r` is type `MyIntegerType`, so the values are not equal.
That is definitely potentially confusing, but I would like to believe
that you would not argue that we should treat r != 0 specially for
integer types. Or, at least, we shouldn't treat it any differently
than r != 1. And, obviously, `r == nil` should not be true if r
happens to be `0`.
I think the reason it feels different for pointer types is that we,
probably incorrectly, chose to use the same identifier, `nil`, to
represent the zero value both for pointers and for interfaces.
Suppose we had given the zero value of interface types the name
`nilinterface`. Then the situation for pointers would be the similar
to that for integers. Writing `r != nilinterface` would be equivalent
to `r != nil` today: it would test whether the interface itself is
nil. `r != nil` would be a compilation error, because, unlike `0`,
there is no default type for `nil`.
If we do change something in this area for Go 2, which we probably
won't, my preference would definitely be to introduce `nilinterface`
rather than to further confuse the meaning of `r != nil`.
Ian