我已经读过this blog post。每个解释都如此清晰和可以理解。我的意思是, slice 的容量增加时它们是如何工作的。但是我对这种行为的反面有疑问。当 slice 的容量减少时,它们的表现如何?考虑以下示例:

var numbers = [8]int{1, 11, 78, 81, 101, 344, 65, 13}
fmt.Printf("len=%d, cap=%d\n", len(numbers), cap(numbers)) // len=8, cap=8

numbers2 := numbers[:4]
fmt.Printf("len=%d, cap=%d\n", len(numbers2), cap(numbers2)) // len=4, cap=8

对于numbers2来说是如此明显。新创建的数组的容量将设置为新 slice 中元素数量的两倍。但考虑到此示例的行为不同:
numbers3 := numbers[1:5]
fmt.Printf("len=%d, cap=%d\n", len(numbers3), cap(numbers3)) // len=4, cap=7

numbers4 := numbers[3:8]
fmt.Printf("len=%d, cap=%d\n", len(numbers4), cap(numbers4)) // len=5, cap=5

我想知道那是什么意思?有没有适当的方法来增加容量计算公式?

最佳答案

slice 规则在Spec: Slice expressions中进行了描述。

在您的示例中numbersarray。对数组进行 slice 时,所得 slice 的容量将是从所得 slice 的第一个元素到数组的最后一个元素的元素数。对slice进行 slice 时,结果的容量是从第一个元素到原始 slice 的容量的元素数量。

因此numbers2 := numbers[:4],低索引被省略,因此默认为0,因此结果将具有8 - 0 = 8的容量(numbers数组的大小)。

numbers3 := numbers[1:5]中,结果将具有7的容量,因为结果中的第一个元素在索引1处,所以在8 - 1 = 7处。

numbers4 := numbers[3:8]中,容量为8 - 3 = 5

注意:这是在使用“简单” slice 表达式时,即在 slice 表达式中仅提供2个索引(形式为a[low : high])时。还有一个“完整” slice 表达式,其形式为a[low : high : max],该表达式还通过将其设置为max - low来控制所得 slice 的容量。

查看相关问题:

Go slices - capacity/length?

Go slice length is capacity -1, why?

Slicing: Out of bounds error in Go

Slices in Go: why does it allow appending more than the capacity allows?

关于arrays - slice 的容量减少时如何表现?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44862762/

10-15 21:58