将一个元素附加到零分片将容量增加两倍 [英] Appending one element to nil slice increases capacity by two

查看:84
本文介绍了将一个元素附加到零分片将容量增加两倍的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  var s1 [] int // len(s1)== 0,cap( s1)== 0 

我追加了一个元素:

  s2:= append(s1,1)// len(s2)== 1,cap(s2)== 2 

为什么将一个元素追加到零分片将容量增加2?



使用 fmt.Printf 打印切片显示如下:

 < code $ [] // s1 
[1] // s2

I我也很困惑,为什么重新切片 s2 [0:2] 显示的零不在原始切片中,也没有附加到它上面:

  [1,0] // s2 [0:2] 


解决方案

Go可以为您提供比您请求的更多容量。这通过减少所需的分配数量(可能还有复制)来提高性能。容量只是在需要另一次分配之前保留的空间量。



如果您在此片上附加5个元素,至少在我的实验中,容量为8。这应该不会令人惊讶,但也不应该依赖。在不同的平台或编译器的不同版本中,只要容量足够大(等于或大于长度),实际结果可能会不同。



切片的上限索引是定义为其容量


对于数组或字符串,如果0 <= low <= high <= len(a),则索引在范围内,否则它们超出范围。对于切片,索引上限是切片容量上限(a),而不是长度。一个常量索引必须是非负的并且可以用int类型的值表示;对于数组或常量字符串,常量指数也必须在范围内。如果两个指数都是常数,则它们必须满足低于< =高。如果指数在运行时超出范围,就会发生运行时恐慌。


这就是为什么阅读过去的长度不是引起恐慌。即使如此,你也不应该将这些零作为切片的一部分。它们可以通过切片进行索引,但是 fmt.Printf(s2)会正确显示它们,因为它们不是切片的一部分。不要用这种方式表示。



一般来说,你想看的是长度,而不是容量。容量大部分是可读的,有助于性能优化。

I have a nil slice:

var s1 []int // len(s1) == 0, cap(s1) == 0

Which I append one element to:

s2 := append(s1, 1) // len(s2) == 1, cap(s2) == 2

Why is appending one element to a nil slice increases the capacity by 2?

Printing the slices using fmt.Printf shows the following:

[] // s1
[1] // s2

I am also confused about why re-slicing s2[0:2] shows a zero which was not in the original slice nor appended to it:

[1,0] // s2[0:2]

解决方案

Go is free to provide you more capacity than you request. This improves performance by reducing the number of allocations (and possibly copying) that are required. Capacity is just the amount of space reserved before another allocation would be required.

If you append 5 elements to this slice, at least in my experiments, the capacity is 8. This shouldn't be surprising, but also shouldn't be relied on. On different platforms, or different versions of the compiler, the actual result may be different, as long as the capacity is "sufficiently large" (equal to or greater than length).

The upper index bound of a slice is defined as its capacity:

For arrays or strings, the indices are in range if 0 <= low <= high <= len(a), otherwise they are out of range. For slices, the upper index bound is the slice capacity cap(a) rather than the length. A constant index must be non-negative and representable by a value of type int; for arrays or constant strings, constant indices must also be in range. If both indices are constant, they must satisfy low <= high. If the indices are out of range at run time, a run-time panic occurs.

This is why reading past the length is not causing a panic. Even so, you shouldn't think of those zeros as part of the slice. They are indexable by the slice, but fmt.Printf(s2) would correctly not show them because they are not part of the slice. Don't subscript this way.

In general, you want to be looking at length, not capacity. Capacity mostly is readable to assist in performance optimization.

这篇关于将一个元素附加到零分片将容量增加两倍的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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