将项追加到最大大小切片时的追加行为

  • 本文关键字:追加 切片 go slice
  • 更新时间 :
  • 英文 :


我对附加到已经具有最大可能大小的切片时的行为感到困惑。

据我所知,根据您的系统,切片的最大大小可以是int32或int64。

当执行test := make([]struct{},math.MaxInt64+1)时,我得到了错误len argument too large in make([]struct {}),这在我的预期范围内。但在做类似的事情时

test := make([]struct{},math.MaxInt64)
for i:=0;i<100 ; i++ {
test = append(test, struct{}{})
}
fmt.Println(len(test))

我预计程序会死机,但令人惊讶的是,代码运行时没有任何问题,len返回了一个带有-9223372036854775709的溢出值。

有人可能会详细说明这种行为吗?

(我使用的是go1.11.2-linux/amd64(

规范说明了任何切片的长度和容量:

在任何时候,以下关系成立:

0 <= len(s) <= cap(s)

这显然违反了,因为长度变为负数,因此小于0。所以这是一个错误,已经报告了,可以在这里跟踪进度:https://github.com/golang/go/issues/29190

伊恩·兰斯·泰勒证实这是一个错误,而不是它应该如何工作。正确的行为是恐慌性地说growslice: cap out of range,它应该源自slice.go / growslice()函数(growslice()是从append()调用的(。

如果我们将您的示例稍微修改为:

s := make([]struct{}, math.MaxInt32-2)
fmt.Println(len(s), cap(s))
for i := 0; i < 5; i++ {
s = append(s, struct{}{})
fmt.Println(len(s), cap(s))
}

并在Go Playground:上运行

2147483645 2147483645
2147483646 2147483646
2147483647 2147483647
-2147483648 2147483647
-2147483647 2147483647
-2147483646 2147483647

正如我们所看到的,一旦容量在32位体系结构上达到MaxInt32,在64位体系结构中达到MaxInt64,容量就会停止增长。

最新更新