go - 调整切片大小 - 是否检查 `len(slice) > 1` 或 `newCap > 2*len(slice)`
问题描述
在Go Programming Language书中,作者给出了以下函数的代码示例,该append()
函数接受 a[]int
和 an作为参数int
,并将相应地处理调整大小:
// gopl.io/ch4/append
func appendInt(x []int, y int) []int {
var z []int
zlen := len(x) + 1
if zlen <= cap(x) {
// There is room to grow. Extend the slice.
z = x[:zlen]
} else {
// There is insufficient space. Allocate a new array.
// Grow by doubling, for amortized linear complexity.
zcap := zlen
if zcap < 2*len(x) { // Question: Why not len(x) > 1?
zcap = 2 * len(x)
}
z = make([]int, zlen, zcap)
copy(z, x)
}
z[len(x)] = y
return z
}
问题
为什么最里面的支票写成if zcap < 2*len(x)
而不是等价的if len(x) > 1
?
后者对我来说似乎更清楚,并表明如果初始切片的长度为 0 或 1,我们不会在添加新元素后分配额外的容量。
等价的细节zcap < 2*len(x)
和len(x) > 1
我们可以看到 的值zcap
是从 赋值的zlen
,而后者又具有 值len(x) + 1
,所以如果我们安排不等式:
zcap < 2*len(x)
代入 后zcap := zlen
,我们得到:
zlen < 2*len(x)
代入 后zlen := len(x) + 1
,我们得到:
长度(x)+ 1 < 2*长度(x)
重新排列后,我们得到:
长度 (x) > 1
解决方案
你是对的,zcap < 2*len(x)
相当于len(x) > 1
。您可以在此功能中完全替换zcap < 2*len(x)
为。len(x) > 1
但根据源码,还有一个函数名为appendslice
. 在此功能中,您无法进行替换。
我认为作者zcap < 2*len(x)
仅用于保持两个功能一致。这里的主要目的是避免频繁分配。
推荐阅读
- python - 在 PowerShell 中将值添加到嵌套对象中,就像在 Python 中一样
- python - 如何使用 Python 访问 Firestore 地理点对象的纬度和经度(这应该很容易!)?
- python - Pandas dataframe plot():x轴日期标签显示但不显示数据
- dynamics-crm - Dynamics CRM 实体安全角色
- javascript - Mongoose:“无法读取未定义的属性 'forEach'”
- python - 无法使用 Subprocess.Popen() 打开文件
- pdf - 获取 AATL 证书以在我的基于云的服务中使用
- python - 所有测试返回 json.decoder.JSONDecodeError:
- xamarin - MvvmCross CloseTo ViewModel
- python - 试图在我的设备上运行程序......我仍然遇到这个问题,我试图解决它,但我从来没有设法