将项目附加到最大尺寸切片时附加行为

时间:2018-12-12 12:32:10

标签: 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)

1 个答案:

答案 0 :(得分:4)

规范说明了任何切片的length and capacity

  

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

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

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

Ian Lance Taylor确认这是一个错误,而不是其工作方式。正确的行为应该是growslice: cap out of range惊慌失措,它应该源自slice.go / growslice()函数({{1}被称为growslice())。

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

append()

并在Go Playground上运行它:

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))
}

我们可以看到,容量在32位体系结构上达到2147483645 2147483645 2147483646 2147483646 2147483647 2147483647 -2147483648 2147483647 -2147483647 2147483647 -2147483646 2147483647 ,在64位体系结构上达到MaxInt32时就停止增长。