在golang中有nil slice和empty slice有什么意义? [英] What is the point of having nil slice and empty slice in golang?

查看:24
本文介绍了在golang中有nil slice和empty slice有什么意义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

区分 nil 切片有什么意义,即.未初始化的切片和空切片,即.已初始化但切片为空?

What is the point of differentiating between a nil slice, ie. uninitialized slice, and an empty slice, ie. initialized but empty slice?

我理解其中的区别,但我想知道这两种情况之间存在细微差别的动机是什么?出于所有意图和目的,使用 nil 切片和空切片时,它们的行为是相同的.

I understand the difference, but I'm wondering what the motivation is behind having the subtle difference between the two cases? For all intents and purposes, a nil slice and an empty slice behave the same when using them.

似乎如果 Go 开发人员只有一种情况,例如只允许空切片,它会简化思维模型并消除细微错误的来源.

It seems as though if Go developers just had one case, for example only allowed empty slices, it would have simplified the mental model and eliminated sources of subtle bugs.

创建这两个用例是否有原因?

Is there a reason why those two use cases were created?

推荐答案

nil 切片值不需要分配.如果您想在切片中构建某些东西,这可能会有所不同,但通常不会附加任何数据,因此切片可能保持 nil,因此完全不需要分配.

A nil slice value needs no allocation. That might make a difference in cases where you want to build something in a slice, but often there will be no data to be appended, so the slice may remain nil, so no allocation will be required altogether.

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

An empty slice might require an allocation, even if its capacity is zero.

同样一个空切片意味着它的长度是0,但它的容量可能不是;因此,对于所有意图和目的,nil 切片和空切片在使用它们时的行为相同是不正确的.".您可以分配一个长度为 0 且容量大的切片,优化进一步追加以避免分配(和复制):

Also an empty slice means its length is 0, but its capacity may not be; so it's not true that "For all intents and purposes, a nil slice and an empty slice behave the same when using them.". You can allocate a slice with 0 length and a big capacity, optimizing for further appends to avoid allocations (and copying over):

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 上试试):

Output of the above (try it on the Go Playground):

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

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

What do we see? In the first example we created an empty slice with 0 length and 0 capacity. If we append an element to it, its length will become 1 (obviously), and its capacity increased to 2. This is because under the hood append() allocated a new array with size of 2 (thinking of future growth), copied the existing elements over (which was none in this case), and assigned the new element.

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

In the second case we started with an empty slice but with a capacity of 10. This means we can append 10 elements to it without causing a new allocation and copying existing elements. This can be a big plus when slices are big and this needs to be done many times.

这篇关于在golang中有nil slice和empty slice有什么意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆