英文:
Go slices - capacity/length?
问题
尝试从教程中学习Go语言,有一个非常基础的问题:
为什么 c
的值是 [0,0]
,长度为2呢?b
最初并没有被置为零,所以它是 []
。那么将 c
设置为 b[:2]
是否会将前两个元素置为零?
另外,为什么 d
的容量是3呢?感到非常困惑。
提前感谢你的回答。
英文:
Trying to learn Go from the tutorial right now, and have a pretty basic question:
func main() {
a := make([]int, 5)
// [0,0,0,0,0] len=5 cap=5
b := make([]int, 0, 5)
// [] len=0 cap=5
c := b[:2]
// [0,0] len=2 cap=5
d := c[2:5]
// [0,0,0] len=3 cap=3
}
Why does c
look like [0,0]
and have length 2? b
was not originally zero'ed hence it being []
. So does setting c
to b[:2]
zero out the first two elements?
Also, why is the capacity of d
3? Very confused.
Thanks in advance.
答案1
得分: 22
你的所有变量都具有切片类型。切片有一个支持的数组。在Go语言中,无法访问未初始化的变量。如果在创建新变量时没有显式提供值,它们将被初始化为变量类型的零值。
这意味着当你使用make([]int, 0, 5)
创建一个切片时,它也会创建一个支持的数组,支持的数组将被初始化为其零值,并且这个零值数组将被切片。数组类型的零值是一个具有每个元素类型的零值的数组。
因此,即使你没有显式将支持的数组的每个元素设置为0
,它们也会自动被置为零。所以当你执行c := b[:2]
时,它将切片b
,并且c
的长度为2,这两个元素将是0
。
当你执行d := c[2:5]
时,它切片了c
,它的长度将是5-2 = 3
,它的容量也将是5-2 = 3
,因为切片一个切片将导致一个新的切片,它与相同的支持的数组共享,并且容量将是支持的数组的第一个元素到最后一个元素(除非你使用一个完整的切片表达式,它还控制了结果切片的容量)。
对于想要理解切片和数组的新手来说,以下是必读的博文:
The Go Blog: Go Slices: usage and internals
The Go Blog: Arrays, slices (and strings): The mechanics of 'append'
英文:
All your variables have a slice type. Slices have a backing array. In Go you can't access uninitialized variables. If you don't explicitly provide a value when you create a new variable, they will be initialized with the zero value of the variable's type.
This means when you create a slice with make([]int, 0, 5)
, it also creates a backing array, the backing array will be initialized with its zero value, and this zeroed array will be sliced. The zero value of an array type is an array having the zero value of element type for each of its elements.
So even though you didn't explicitly set every elements of the backing array to 0
, they will be zeroed automatically. So when you do c := b[:2]
, it will slice the b
slice, and c
will have a length of 2, and those 2 elements will be 0
.
And when you do d := c[2:5]
that slices the c
slice, its length will be 5-2 = 3
, and its capacity will also be 5-2 = 3
because slicing a slice will result in a new slice which shares the same backing array, and the capacity will be the first element till the last of the backing array (unless you use a full slice expression which also controls the resulting slice's capacity).
Must-read blog posts for newcomers who want to understand slices and arrays:
The Go Blog: Go Slices: usage and internals
The Go Blog: Arrays, slices (and strings): The mechanics of 'append'
答案2
得分: 1
官方文档提到了以下内容:
切片的长度是它包含的元素数量。
切片的容量是从切片中的第一个元素开始计算的底层数组中的元素数量。
所以对于你的第一个问题:
为什么
c
看起来是[0,0]
并且长度为 2?
你的切片 c
是通过 b[:2]
创建的,这意味着它包含了切片 b
中从第 0 个位置到第 1 个位置的元素。因此它只有 2 个元素,所以长度为 2。
所以将
c
设置为b[:2]
会将前两个元素清零吗?(因为b
是[]
)
正如 @icza 提到的,go
默认将它们初始化为 0。通过将 c:=b[:2]
设置,你将 b
初始化为具有 2 个元素,而其容量为 5。
对于你的第二个问题:
为什么
d
的容量是 3?
正如评论者 @Akavall 提到的:
容量是切片可以访问的第一个元素和底层数组的最后一个元素之间的元素数量。
所以在你的情况下,切片 d
可以访问的第一个元素是数组的第 2 个位置的元素,而底层数组的最后一个元素是第 5 个位置。因此,5-2 等于 3。
我在此附上了官方文档中关于切片访问数组的图示表示。
更多关于切片初始化和创建的示例可以在官方文档的后续部分找到。
https://tour.golang.org/moretypes/13
英文:
The official docs mentions that.
> The length of a slice is the number of elements it contains.
> The capacity of a slice is the number of elements in the underlying array, counting from the first element in the slice.
So for your 1st q:
> Why does c look like [0,0] and have length 2?
Your slice c
was created with b[:2]
which means it has elements from 0th to 1st position of the slice b
. Hence it has only 2 elements so length is 2.
> So does setting c
to b[:2]
zero out the first two elements?(since b was
[]`)
Now as @icza mentioned go
initializes them to 0 by default. By setting c:=b[:2]
you initialized b to have 2 elements out of its capacity 5.
For your 2nd q:
> why is the capacity of d
3
As one of the commenters @Akavall mentioned.
> capacity, is the number of elements between the first element that a slice can access and the last element of the underlying array.
So in your case the 1st element your slice d
can access is the 2nd possition element of the array and the last element of underlying array is position 5th. So 5-2 is 3.
I have hereby attached the official diagrammatic representation of slice accessing the array.
More examples of initialization and creation of slices are available further in official documentation.
https://tour.golang.org/moretypes/13
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论