作为接口传递时的 nil 切片不是 nil!为什么?(golang) [英] nil slice when passed as interface is not nil! Why? (golang)
问题描述
看到这个游乐场:http://play.golang.org/p/nWHmlw1W01
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)
}
为什么两个函数的输出不同?
Why the difference in output between the two functions?
推荐答案
诚然,这有点怪癖,但有一个解释.
Admittedly, it's somewhat of a quirk, but there's an explanation for it.
将 interface{}
变量想象成一个由两个字段组成的结构:一个是类型,另一个是数据.([]int
和 nil
).实际上,它在 Go 运行时中看起来就是这样.
Imagine an interface{}
variable as a struct composed of two fields: one is the type and another is the data. ([]int
and nil
). Actually, it looks just like that in the Go runtime.
struct Iface
{
Itab* tab;
void* data;
};
当您将 nil 切片传递给 yes
时,只有 nil
作为值传递,因此您的比较归结为 nil == nil
.
When you pass your nil slice to yes
, only nil
is passed as the value, so your comparison boils down to nil == nil
.
同时,调用 no
会自动将您的变量包装在 interface{}
类型中,并且调用变得类似于 no(interface{[]int, nil})
.所以no
中的比较可以看成interface{[]int, nil} == nil
,在go中结果为false.
Meanwhile, calling no
automatically wraps your variable in an interface{}
type and the call becomes something akin to no(interface{[]int, nil})
. So the comparison in no
could be seen as interface{[]int, nil} == nil
, which turns out to be false in go.
该问题实际上已在 Go 常见问题解答中进行了解释.
The issue is actually explained in the Go FAQ.
这篇关于作为接口传递时的 nil 切片不是 nil!为什么?(golang)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!