理解 Go 接口中的 nil 切片悖论
当将 nil 切片作为接口传递时,为什么结果不是 nil?这种令人困惑的行为可以通过理解 Go 接口的底层实现来解释。
在 Go 中,interface{} 变量本质上是一个双字段结构,由类型描述符和数据值组成,如下所示iface struct:
struct Iface { Itab* tab; void* data; };
现在我们来分析一下提供的代码中的两个函数调用:
<code class="go">yes([]int{}) // output: true no([]int{}) // output: false</code>
yes Function:
中yes 函数,[]int{} 值作为参数 thing 传递。由于 yes 只接受切片参数,因此编译器将 nil 视为零值切片。因此,比较 thing == nil 变为 nil == nil,返回 true。
no Function:
相反,no 函数需要一个接口{}范围。当您传递 []int{} 值时,Go 会自动将其包装在 interface{} 类型中。有效地将其转换为interface{[]int, nil}。比较 thing == nil 现在计算为 interface{[]int, nil} == nil,结果为 false。
Go FAQ 中进一步阐明了这种行为,其中解释了“包含 nil 的接口仅是如果它们的所有成员都为 nil,则等于 nil”(即在本例中,[]int(类型成员)不能为 nil)。
因此,在接口中处理 nil 切片时,它是意识到这种怪癖并考虑底层实现以正确解释行为至关重要。
以上是为什么传递给 Go 接口的 Nil 切片不等于 Nil?的详细内容。更多信息请关注PHP中文网其他相关文章!