为了账号安全,请及时绑定邮箱和手机立即绑定

append() 是否总是扩展所需的最小容量?

append() 是否总是扩展所需的最小容量?

Go
翻翻过去那场雪 2021-06-13 17:15:44
在学习切片时,我有一个疑问: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。然而,精确的扩大(分配新的后备数组)策略并没有在每个细节中指定,以允许编译器人员试验一些附加到此机制的旋钮。


查看完整回答
反对 回复 2021-06-21
?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

我要补充的是,它不仅不能保证切片的容量等于长度,事实上,对于大长度,几乎永远不会出现结果切片的容量等于长度的情况。

append()被提升为vector包的替代品。为此,追加的复杂度必须与vector包中的复杂度相匹配,这意味着追加元素必须具有分摊 O(1) 的复杂度。尽管在语言规范中没有保证这种复杂性,但对于append()现在在 Go 社区中使用的模式来说,它必须有效地工作。

为了append()摊销 O(1),它必须在每次空间用完时以当前容量的固定百分比扩展容量。例如,容量翻倍。想一想,如果每次用完容量翻倍,那么长度和容量只有在长度正好是2的幂(假设它开始是2的幂)的情况下才能相同,这种情况并不常见。


查看完整回答
反对 回复 2021-06-21
  • 2 回答
  • 0 关注
  • 219 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信