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