小编典典

作为接口传递时,nil slice不是nil!为什么?(golang)

go

看到这个游乐场: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)
}

为什么两个函数的输出不同?


阅读 274

收藏
2020-07-02

共1个答案

小编典典

诚然,这有点古怪,但是有一个解释。

想象一个interface{}变量是由两个字段组成的结构:一个是类型,另一个是数据。([]intnil)。实际上,它看起来就像Go运行时中的样子。

struct Iface                                                                                                                   
{                                                                                                                              
    Itab*   tab;                                                                                                               
    void*   data;                                                                                                              
};

当您将nil slice传递给时yes,只会nil将其作为值传递,因此您的比较可简化为nil == nil

同时,调用会no自动将您的变量包装为一种interface{}类型,并且调用变得类似于no(interface{[]int, nil})。因此,in中的比较no可以看成interface{[]int, nil} == nil,这在进行中被证明是错误的。

该问题实际上在Go
FAQ
中得到解释。

2020-07-02