首页 >后端开发 >Golang >为什么 Nil 切片在传递到 Go 中的接口时表现不同?

为什么 Nil 切片在传递到 Go 中的接口时表现不同?

Susan Sarandon
Susan Sarandon原创
2024-11-03 05:32:02301浏览

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

Go 接口中 Nil 切片的特殊行为

在 Go 中,切片可以被赋予 nil 值,这表示一个空切片。然而,当将 nil 切片作为参数传递给需要接口{}的函数时,就会出现令人惊讶的行为差异。

考虑以下 Go 游乐场:

<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>

在上面的例子中,两个函数 yes 和 no 接收相同的 nil 切片作为它们的参数。但是,两个函数的输出不同。 yes 打印 true,表明切片确实为零。不,另一方面,打印 false。

为什么会出现这种差异?答案在于 Go 接口内部表示 nil 切片的方式。

interface{} 变量用于表示各种类型,由两个字段组成:类型和数据指针。当一个 nil 切片传递给需要一个 interface{} 的函数时,它会被包装在一个 interface{} 类型中,并且数据指针被设置为 nil。

在 yes 的情况下,它直接比较nil 的参数,有效地询问切片本身是否为零。此比较返回 true,因为切片确实为空。

但是,no 函数接收包装在 interface{} 中的 nil 切片。这种情况下的比较不仅仅是切片和 nil 之间的比较,而是整个 interface{} 和 nil 之间的比较。在运行时内部,这种比较归结为测试 interface{} 的数据指针是否为 nil,这是 false,因为接口包装器已为其分配了内存。

此行为也记录在 Go 的常见问题解答中:

“将 nil 切片传递给接口的一个常见问题:由于 nil 切片由 nil 接口值表示,因此在测试接口 i(nil 接口)的值时写入 if i == nil 可能会虚假成功是假的)。”

以上是为什么 Nil 切片在传递到 Go 中的接口时表现不同?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn