Home > Article > Backend Development > Why Does a Nil Slice Behave Differently When Passed to an Interface in Go?
The Peculiar Behavior of Nil Slices in Go Interfaces
In Go, slices can be assigned the nil value, which signifies an empty slice. However, when a nil slice is passed as an argument to a function expecting an interface{}, a surprising difference in behavior emerges.
Consider the following Go playground:
<code class="go">package main import "fmt" func main() { var i []int = nil yes(i) // output: true no(i) // output: false } func yes(thing []int) { fmt.Println(thing == nil) } func no(thing interface{}) { fmt.Println(thing == nil) }</code>
In the example above, two functions, yes and no, receive the same nil slice as their argument. However, the output of the two functions differs. yes prints true, indicating that the slice is indeed nil. no, on the other hand, prints false.
Why is there this discrepancy? The answer lies in the way nil slices are represented internally in Go interfaces.
An interface{} variable, used to represent a wide range of types, consists of two fields: a type and a data pointer. When a nil slice is passed to a function expecting an interface{}, it is wrapped in an interface{} type, and the data pointer is set to nil.
In the case of yes, it directly compares the argument to nil, effectively asking if the slice itself is nil. This comparison returns true since the slice is indeed empty.
However, the no function receives the nil slice wrapped in an interface{}. The comparison in this case is not just between the slice and nil but between the entire interface{} and nil. Inside the runtime, this comparison boils down to testing whether the interface{}'s data pointer is nil, which is false because the interface wrapper has allocated memory for it.
This behavior is also documented in Go's FAQ:
"A common problem with nil slices passed to interfaces: since a nil slice is represented by a nil interface value, writing if i == nil may spuriously succeed when testing the value of an interface i (a nil interface is false)."
The above is the detailed content of Why Does a Nil Slice Behave Differently When Passed to an Interface in Go?. For more information, please follow other related articles on the PHP Chinese website!