В спецификации говорится о длине и емкости любого среза:
В любое время выполняется следующее соотношение:
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
Как мы видим, емкость перестает расти, как только она достигает MaxInt32
на 32-разрядных архитектурах и MaxInt64
на 64-разрядных архитектурах.