猿问

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

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 而另一个不是呢?


萧十郎
浏览 274回答 2
2回答

元芳怎么了

就其本身而言,是 的类型切片的[]int拼写。int在:var test1 []int提供[]int变量的类型test1。该行作为一个整体不提供任何值,因此test1被初始化为type 的零值[]int。它的零值是[]int(nil),或者非正式地,就是 nil 。1在:test2 := []int{}提供[]int大括号括起来的初始值设定项列表的类型。也就是说,{}是一个复合文字:一个左大括号,后跟一个元素列表(在本例中为空),后跟一个右大括号。该行的其余部分(:=左侧的 和变量名称)表示一个简短的变量声明。这为变量提供了类型test2,以及空列表生成的值。 []int在这种情况下,空列表生成的值是 的一个空切片int: 1 具有空的2后备存储,长度为零,容量为零。这就是为什么test1is nil 但test2不是:test1保存零值,对于任何切片类型来说,都是nil(nil无论如何转换为该类型之后)。同时test2保存由三部分组成的切片头,该头覆盖由复合文字创建的零长度支持数组。一个 nil 切片——这是一个有点草率的措辞:它意味着一个 slice-of 类型的值,T其实际值[]T(nil)而不是某些由三部分组成的切片头——通常可以用作相同类型。特别是,for i := range x两者x = append(x, newElement)都处理得x == nil“很好”:它们对待它的方式与对待空切片的方式相同。打印切片的例程fmt也执行此操作。31nil本身是无类型的。nil请参阅 Go 规范中变量部分下第一次提到的。2至少在没有使用或类似的情况下,不可能判断unsafe.PointerGo 是否实际为后备数组分配了任何存储空间。您对切片执行的任何操作都可以为其提供一些容量,以便您可以将一些值放入内存中的某个位置,都将或可能只是分配一个新的后备数组。该包有一些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不会表现得很好。

一只名叫tom的猫

这是 nil 和空切片之间的区别。在golang中,如果你声明一个没有值的变量,它的值将成为该变量类型的零值。数组的零值为 nil。不是空切片。可以使用 make 函数或 Shorty 用于 test2 的第二种方法来生成空切片
随时随地看视频慕课网APP

相关分类

Go
我要回答