Why Does a Nil Slice Behave Differently When Passed to an Interface in Go?

Susan Sarandon
Release: 2024-11-03 05:32:02
Original
228 people have browsed it

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>
Copy after login

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!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!