【发布时间】:2020-11-10 09:12:27
【问题描述】:
在Go Programming Language 一书中,作者给出了以下append() 函数的代码示例,该函数接受[]int 和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的值又是len(x) + 1,所以如果我们安排不等式:
zcap
代入zcap := zlen后,我们得到:
zlen
代入zlen := len(x) + 1后,我们得到:
len(x) + 1
重新排列后,我们得到:
len(x) > 1
【问题讨论】:
-
zcap < 2*len(x)条件对我来说毫无意义。实际上,您只有一个极端情况:len(x) == 0,其他一切都可以用newCapacity = len(x) * 2处理 -
zcap 1。您的推导是错误的,因为 len(x) 可以为 0。(可能还有很多其他错误。)
-
@Volker 为什么 zcap 1?
-
@Volker,推导有效。如果 len(x)>1,该代码基本上将容量加倍,但由于某种原因,它用很多词来做到这一点。请注意,此时 len(x)==cap(x),并且仅当 len(x)=0 时才不必将容量翻倍。
-
A,对不起,它不是被零除。我的错。