I have read some text regarding nil slice vs empty slice. I believe I have some basic understanding of the differences between them.
Summary of my understanding: var instance []Type
is nil slice and instance == nil
returns true
; while instance:=[]Type{}
is empty slice and instance != nil
However this particular instance still puzzles me.
Please look at the link below for code. My question is the last 2 cases. https://play.golang.org/p/udyHoOlSeP
Suppose I want to compare two slices, renamed type and interface matching and all. The instance where a receiver can be nil
, even though it's not defined as copy by value; while the argument is copied by value, seems to be non-nil as long as the argument is not untyped.
In the last 2 cases, receiver has been identified as nil
while argument is being processed by :=
so it becomes an empty slice. (But the other == nil
also reports false...) How can I fix this to satisfy the following requirement?
nilslice.Equals(nilslice) // -> true
Further, I tried to define another interface comparing to pointers of interface but failed. Compiler complains that
cannot use p (type *AnotherNullable) as type *PointerComparable in argument to AnotherNullable(nil).Equals: *PointerComparable is pointer to interface, not interface
https://play.golang.org/p/wYO1GKcBds
How can I fix that?
EDIT: Thanks to @zippoxer for all the insights. I learned a lot. I hope new readers too, please don't forget to check out @zippoxer's comment in the answer too!
First, you don't need a pointer to an interface. An interface is already a pointer. See Go: What's the meaning of interface{}?
Just change the Equals method to accept a PointerComparable
instead of a *PointerComparable
. Equals will accept an interface instead of a pointer to an interface, but you can still pass a pointer to a slice/whatever to it. See https://play.golang.org/p/e_Gtq2oAFA
Second, the receiver Nullable
isn't an interface, while the argument you pass to Equals is an interface. That would explain why the Nullable
receiver stays nil and the Comparable
argument isn't nil although it's underlying slice is. The thing is, the Comparable
argument is an interface that points to something, so whatever it points to, it won't be nil.
This code explains the problem:
var a interface{}
fmt.Println(a == nil) // true, the interface doesn't point to anything
var someNilSlice []int
fmt.Println(someNilSlice == nil) // true, just some nil slice
a = someNilSlice
fmt.Println(a == nil) // false, now the interface does point to something