{] int {}和[] int in go有什么区别?

时间:2019-12-16 02:31:48

标签: go

这里有两个不同的定义,但是有什么区别? 我尝试了以下方法:

func main() {
    var test1 []int
    test2 := []int{}

    if test1 == nil {
        fmt.Println(1)
    }
    if test2 == nil {
        fmt.Println(2)
    }
    fmt.Println("test1:", test1)
    fmt.Println("test2:", test2)
}

这是输出:

1
test1: []
test2: []

但是为什么test1为nil但另一个不是?

2 个答案:

答案 0 :(得分:8)

[]int本身是int slice类型的拼写。

在:

var test1 []int

[]int提供了变量test1的类型。整个行提供 no 值,因此test1被初始化为类型[]int的{​​{3}}。零的值为[]int(nil),或者非正式地为零。 1

在:

test2 := []int{}

[]int提供了用大括号括起来的初始化程序列表的类型。也就是说,{}zero value:右括号,然后是元素列表(在这种情况下为空),后跟右括号。该行的其余部分(:=和左侧的变量名称)表示composite literal。这样,变量test2类型 []int以及空列表产生的

在这种情况下,空列表产生的值是int的空片:其中一个空的 2 后备存储,长度为零,容量为零。

这就是test1为零而test2不是零的原因:test1保持零值,对于任何切片类型,该值均为nil(在nil之后无论如何都会转换为该类型)。同时,test2拥有三部分的切片标头,该标头涵盖了由复合文字创建的零长度后备数组。

nil slice-这有点草率:它表示类型为T的slice-of类型的值,其实际值为[]T(nil),而不是由三部分组成的slice头-通常可以用作相同类型的空(长度为零)切片。特别是,for i := range xx = append(x, newElement)都“很好”地处理x == nil:它们对待空切片的方式相同。打印切片的fmt例程也可以执行此操作。 3


1 nil本身是 untyped 。请参见short variable declaration中对nil的第一次提及。

2 至少在不使用unsafe.Pointer或类似的情况下,不可能知道Go是否实际上为后备阵列分配了任何存储空间。您对切片执行的任何操作都会为其提供一定的容量,以便您可以将某些值放入内存中的某个位置,这将或可能只是分配一个 new 后备数组。 unsafe软件包提供了一些技巧,可以窥探Go运行时,但总的来说,您不需要这样做,也不应该。

3 相比之下,map类型的播放效果不太好。如果x是(可能是非正式的)一片,可能是零,而m是一张可能是零的地图,我们可以这样做:

x = append(x, newElem)

但我们不能这样做:

m[key] = newElem

我们必须首先检查m是否为nil,如果是,则分配一个空映射:

if m == nil {
    m = make(...) // put in the right type here
}
m[key] = newElem

因此使用是相对常见的:

var x []T
m := map[string]T{}

彼此相邻,因为x的行为会很好,而m的行为会不会。

答案 1 :(得分:0)

nil和空片之间的区别。在golang中,如果您声明的变量没有值,则其值将成为变量类型的零值。数组的零值为nil。不是空片。空切片可以通过make函数或shorty生成,该方法是您用于test2的第二种方法