It seems a very bad idea, to require the common case to go through some package or else get lint-warned.
Checking "x == nil" is the correct way to check whether a value contains a valid implementation of an interface - and a nil-pointer with the correct method set is, as far as you should be concerned, such a valid implementation. If you indeed want to check whether the contained value is a nil-pointer (I'm having actual trouble coming up with a scenario where you'd want to do that - except cases like encoding/json, where you need to use reflection anyway), you have to check that explicitly, either by converting nil into the correct type (i.e. "x == (*T)(nil)"), or by type-asserting. That is the uncommon case, so it's fine having to jump through a couple of hoops for hat. What *might* make more sense, is trying to lint whether a nil-pointer is used for an interface, and the corresponding methods are not nil-safe. I.e. do the "is a nil-pointer a valid value for this interface" check where it belongs: At the point where the interface-conversion happens (when assigning it to an interface-typed variable or passing it as an interface-typed parameter). On Wed, Nov 1, 2017 at 6:09 PM, Jack Christensen <j...@jackchristensen.com> wrote: > > > On 11/01/2017 09:31 AM, Ian Lance Taylor wrote: > >> On Wed, Nov 1, 2017 at 4:18 AM, <oju...@gmail.com> wrote: >> >>> Ayan, imagine I am part of a development team. In our program I have a >>> pointer r: >>> >>> r *myType >>> >>> My variable r can be nil, because that is a valid situation. It is used >>> in >>> dozens of places, like this: >>> >>> if r != nil { >>> r.doSomething() >>> } >>> >>> That is a very usual idiom, no only in Go, but in many languages. Every >>> programmer is acquainted to that. >>> >>> Then, years later, other programmer in my team decides to create an >>> interface to better capture a new understanding of the problem at hand, >>> changing the type of r to: >>> >>> r myInterface >>> >>> Subtly, the meaning of >>> >>> if r != nil { >>> r.doSomething() >>> } >>> >>> changes. Under the right circumstances our software starts to behave >>> strangely. What? >>> >>> This problem is dangerous because it is so subtle. We will read our old >>> code >>> time and again to no avail, because everything seems fine and no one has >>> changed that "if r != nil r.doSomething" in ages. >>> >>> As Dave Cheney said in >>> https://github.com/golang/go/issues/21538#issuecomment-323561094 that >>> could >>> be solved: >>> >>> "by making an nil interface and an interface which contains a type who's >>> value is nil also equal to nil." >>> >> 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 >> >> Perhaps a small package and linter could solve this without requiring a > language change. The package would expose either a NilInterface value or a > IsNilInterface method. Users of the package would either compare to the > pkg.NilInterface or call the pkg.IsNilInterface method. Then the linter > could warn on all direct interface comparisons to nil. > > Jack > > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.