我已经读过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中进行了描述。
在您的示例中numbers
是array。对数组进行 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/