我已阅读this blog post。每一个解释都是如此清晰易懂。而且我明白了切片在容量增加时的作用。但我对这种行为的反面有疑问。当容量减少时,切片如何表现?考虑这个例子:
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
来说,这是显而易见的。新创建的数组的容量将设置为新切片中元素数量的两倍。但考虑到这个例子,它的表现不同:
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
我想知道那是什么意思?是否有适当的容量计算公式如增加?
答案 0 :(得分:3)
切片规则在Spec: Slice expressions。
中描述在您的示例中numbers
是array。切片数组时,生成的切片的容量将是从结果切片的第一个元素到数组的最后一个元素的元素数。当您对slice进行切片时,结果的容量是从第一个元素到原始切片容量的元素数。
所以numbers2 := numbers[:4]
,低索引被省略,因此默认为0
,因此结果的容量为8 - 0 = 8
(numbers
数组的大小)。< / p>
在numbers3 := numbers[1:5]
中,结果的容量为7
,因为结果中的第一个元素位于索引1
,因此8 - 1 = 7
。
在numbers4 := numbers[3:8]
中,容量为8 - 3 = 5
。
注意:这是您使用&#34;简单&#34;切片表达式,即只在切片表达式中提供2个索引(其形式为a[low : high]
)。还有一个完整的&#34;切片表达式,其形式为a[low : high : max]
,通过将切片的容量设置为max - low
来控制生成切片的容量。
查看相关问题:
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?