Go 中的切片:为什么它允许附加超过容量允许的内容? [英] Slices in Go: why does it allow appending more than the capacity allows?

查看:21
本文介绍了Go 中的切片:为什么它允许附加超过容量允许的内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Go 中制作 slicecapacity 参数对我来说没有多大意义.例如,

The capacity parameter in making a slice in Go does not make much sense to me. For example,

aSlice := make([]int, 2, 2) //a new slice with length and cap both set to 2
aSlice = append(aSlice, 1, 2, 3, 4, 5) //append integers 1 through 5
fmt.Println("aSlice is: ", aSlice)  //output [0, 0, 1, 2, 3, 4, 5]

如果切片允许插入的元素比容量允许的多,为什么我们需要在 make() 函数中设置它?

If the slice allows inserting more elements than the capacity allows, why do we need to set it in the make() function?

推荐答案

内置 append() 函数使用指定的切片将元素追加到如果它有足够大的容量来容纳指定的元素.

The builtin append() function uses the specified slice to append elements to if it has a big enough capacity to accomodate the specified elements.

但是如果传递的切片不够大,它分配一个新的、足够大的切片,将元素从传递的切片复制到新切片并将元素附加到新切片.并返回这个新切片.引用 append() 文档:

But if the passed slice is not big enough, it allocates a new, big enough slice, copies the elements from the passed slice to the new slice and append the elements to that new slice. And returns this new slice. Quoting from the append() documentation:

append 内置函数将元素附加到切片的末尾.如果它有足够的容量,目标将被重新切片以容纳新元素.如果没有,将分配一个新的底层数组.Append 返回更新后的切片.因此有必要将 append 的结果存储在保存切片本身的变量中:

The append built-in function appends elements to the end of a slice. If it has sufficient capacity, the destination is resliced to accommodate the new elements. If it does not, a new underlying array will be allocated. Append returns the updated slice. It is therefore necessary to store the result of append, often in the variable holding the slice itself:

make制作切片时,如果长度和容量相同,容量可以省略,此时默认为指定长度:

When making a slice with make if the length and capacity are the same, the capacity can be omitted, in which case it is defaulted to the specified length:

// These 2 declarations are equivalent:
s := make([]int, 2, 2)
s := make([]int, 2)

还要注意 append() 在切片的最后一个元素之后追加元素.并且上面的切片在声明之后已经有 len(s) == 2 所以如果你甚至只附加 1 个元素到它,它会导致重新分配,如本例所示:

Also note that append() appends elements after the last element of the slice. And the above slices already have len(s) == 2 right after declaration so if you append even just 1 element to it, it will cause a reallocation as seen in this example:

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

输出:

[0 0] 2 2
[0 0 1] 3 4

所以在你的例子中你应该做的是这样的:

So in your example what you should do is something like this:

s := make([]int, 0, 10) // Create a slice with length=0 and capacity=10
fmt.Println(s, len(s), cap(s))
s = append(s, 1)
fmt.Println(s, len(s), cap(s))

输出:

[] 0 10
[1] 1 10

如果您想更详细地了解切片,我推荐以下博客文章:

I recommend the following blog articles if you want to understand slices in more details:

Go Slices:用法和内部结构

数组、切片(和字符串):追加"的机制

这篇关于Go 中的切片:为什么它允许附加超过容量允许的内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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