在学习切片时,我有一个疑问:append() 是否总是扩展所需的最小容量?a := make([]byte, 0)a = append(a, 1, 2, 3)cap(a) == 3 // will this be always true?// or the assumption may not hold since the underlying implementation of append()// is not specified.
2 回答
呼啦一阵风
TA贡献1802条经验 获得超6个赞
不,在这种情况下不能保证。该规范说:
append(s S, x ...T) S // T is the element type of S
如果 s 的容量不足以容纳附加值,则 append 分配一个新的、足够大的切片,以适合现有切片元素和附加值。因此,返回的切片可能引用不同的底层数组。
(强调我的)
在你的情况,显然任何容量> = 3是足够大的,所以你可以依靠的cap >= 3
,但你不能依靠cap == 3
。
当然,您可以假设在这种情况下上限不会是,例如 1e6 或 1e9 或 1e12。然而,精确的扩大(分配新的后备数组)策略并没有在每个细节中指定,以允许编译器人员试验一些附加到此机制的旋钮。
摇曳的蔷薇
TA贡献1793条经验 获得超6个赞
我要补充的是,它不仅不能保证切片的容量等于长度,事实上,对于大长度,几乎永远不会出现结果切片的容量等于长度的情况。
append()
被提升为vector
包的替代品。为此,追加的复杂度必须与vector
包中的复杂度相匹配,这意味着追加元素必须具有分摊 O(1) 的复杂度。尽管在语言规范中没有保证这种复杂性,但对于append()
现在在 Go 社区中使用的模式来说,它必须有效地工作。
为了append()
摊销 O(1),它必须在每次空间用完时以当前容量的固定百分比扩展容量。例如,容量翻倍。想一想,如果每次用完容量翻倍,那么长度和容量只有在长度正好是2的幂(假设它开始是2的幂)的情况下才能相同,这种情况并不常见。
- 2 回答
- 0 关注
- 219 浏览
添加回答
举报
0/150
提交
取消