In Go nil is a special identifier that represents a "zero value" for several types (pointers, interfaces, functions, slices, channels).
"unset" would be a "zero value" for interfaces so that nil could be "interface that has a type but whose value is an zero value of a pointer or function or slice or a channel.
This is inconsistent - now you have 2 identifiers to represent a concept of "zero value".
go has _three_ different concepts: what is now called nil has instances from two classes, let's call them nil.type and nil.interface.
Discussion is about whether it would be better to require programmers to explicitly specify the .type or .interface part in the code they write, or to let the compiler infer it from its arguments (with the special case that it should assume that, in nil == nil, both have the same meaning, so that it evaluates to true)
I think I would favor having two separate names in my source code, with the caveat that the compiler should make it illegal to write x == nil.interface if x is a type and vice versa, but I know too little about go to claim that's really a good idea, and also think it would change if go got generics (and maybe, the code generation thing it has now in place of generics (go generate) already would change my opinion, if I took time to think it over)
We're in agreement but I think <type>.<value> is a somewhat universal syntactic construct.
I think this is the crux of the problem. OP's confusion would be addressed by
var foo someType = someType.nil
var bar someInterface = foo
if (bar == interface.nil) // prints false without confusionusing the same word to represent these two things makes this more confusing, because it violates our intuitive sense of algebraic laws (a = nil, b = a => a == nil); using different words for the zero-value of interface and pointer would break this false intuition (a = nil, b = a =/> a == unset), and save a lot of confusion.
fmt.Println(bar.(SomeType) == nil) // this will print true
You need to explicitly convert the interface to a specific type (as above) before you can compare whether or not it points to a concrete value. Since SomeInterface could point to any type (by implementing all the members of SomeInterface, you can make any type be of SomeInterface). This is because variables that have a interface type are never nil.I wouldn't call this a design issue, I believe this was done very purposefully and it makes perfect sense to me and other long time Go developers. The biggest problem I've seen with learning Go is for others coming from Ruby / Java / PHP / etc languages, who have this expectation of what "null" is (or nil as the case may be) and what "interfaces" are. The key to learning Go is to come at it with the thinking of C/C++.
Right now a pointer to a type that is zero is called "nil". Similarly, an interface that contains zero for both the type and the value is called "nil".
This is really confusing because
If instead you called the zero-value of interface something else, say "unset", it would be a lot less confusing. I first encountered this idea in this reddit thread:https://www.reddit.com/r/golang/comments/4injtt/understandin...