在golang中使用nil切片和空切片有什么意义?

问题描述 投票:2回答:1

区分零切片的意义何在,即。未初始化的切片和一个空切片,即。初始化但空片?

我理解这种差异,但我想知道这两种情况之间存在细微差别的动机是什么?对于所有意图和目的,使用nil切片和空切片时表现相同。

似乎Go开发人员只有一个案例,例如只允许空切片,它会简化心智模型并消除微妙错误的来源。

有没有理由为什么创建这两个用例?

go null slice
1个回答
3
投票

nil切片值不需要分配。这可能会在您想要在切片中构建内容的情况下产生影响,但通常不会附加数据,因此切片可能保留nil,因此不需要完全分配。

空切片可能需要分配,即使其容量为零。

空切片也意味着它的长度为0,但其容量可能不是;所以“对于所有意图和目的来说,使用它们时,nil切片和空切片的行为都是一样的。”您可以分配0长度和大容量的切片,优化进一步的附加以避免分配(和复制):

s := make([]int, 0)
fmt.Println(s, len(s), cap(s))
s = append(s, 1)
fmt.Println(s, len(s), cap(s))

s = make([]int, 0, 10)
fmt.Println(s, len(s), cap(s))
s = append(s, 1)
fmt.Println(s, len(s), cap(s))

以上输出(在Go Playground上试试):

[] 0 0
[1] 1 2
[] 0 10
[1] 1 10

我们看到了什么?在第一个例子中,我们创建了一个0长度和0容量的空切片。如果我们向它附加一个元素,它的长度将变为1(显然),并且其容量增加到2.这是因为在引擎盖下append()分配了一个大小为2的新数组(考虑未来增长),复制了现有元素结束(在这种情况下没有),并分配了新元素。

在第二种情况下,我们从一个空切片开始,但容量为10.这意味着我们可以向其追加10个元素,而不会导致新的分配和复制现有元素。当切片很大时,这可能是一个很大的优势,这需要多次完成。

© www.soinside.com 2019 - 2024. All rights reserved.