英文:
How does the slices behave when their capacity reduce?
问题
我已经阅读了这篇博客文章。每个解释都非常清晰易懂。我明白了当切片的容量增加时它们是如何工作的。但是我对相反的行为有一个问题。当切片的容量减少时,它们是如何工作的?考虑以下示例:
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
我想知道这其中的原因是什么?是否有像增加容量那样的适当的容量计算公式呢?
英文:
I have already read this blog post. Every explanation is so clear and understandable. And I got the point that how slices are acting when their capacity is increasing. But I have a question about the opposite of this behaviour. How do the slices behave when their capacity is reduced? Considering this example:
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
For numbers2
it is so obvious. The capacity of the newly created array will be set to two folds the number of elements in the new slice. But considering this example its acting differently:
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
I was wondering about that what was the point? Is there any proper way of capacity calculation formula like increasing?
答案1
得分: 3
切片的规则在规范:切片表达式中有描述。
在你的例子中,numbers
是一个数组。当你对数组进行切片时,结果切片的容量将是从结果切片的第一个元素到数组最后一个元素的元素数量。当你对切片进行切片时,结果的容量是从第一个元素到原始切片的容量的元素数量。
所以 numbers2 := numbers[:4]
,省略了低索引,因此默认为 0
,所以结果的容量为 8 - 0 = 8
(即 numbers
数组的大小)。
在 numbers3 := numbers[1:5]
中,结果的容量为 7
,因为结果中的第一个元素的索引是 1
,所以 8 - 1 = 7
。
在 numbers4 := numbers[3:8]
中,容量将为 8 - 3 = 5
。
注意: 这是当你使用一个“简单”的切片表达式时,即在切片表达式中只提供2个索引(形式为 a[low : high]
)。还有一个“完整”的切片表达式,形式为 a[low : high : max]
,它通过将容量设置为 max - low
来额外控制结果切片的容量。
参考相关问题:
https://stackoverflow.com/questions/36683911/go-slices-capacity-length/36689864#36689864
https://stackoverflow.com/questions/31685620/go-slice-length-is-capacity-1-why/31685840#31685840
https://stackoverflow.com/questions/33859066/slicing-out-of-bounds-error-in-go/33859638#33859638
英文:
Rules of slicing is described in the Spec: Slice expressions.
In your example numbers
is an array. When you slice an array, the resulting slice's capacity will be the number of elements from the resulting slice's first element till the last element of the array. When you're slicing a slice, the capacity of the result is the number of elements from the first element till the capacity of the original slice.
So numbers2 := numbers[:4]
, low index is omitted and therefore defaults to 0
, so the result will have a capacity of 8 - 0 = 8
(the size of numbers
array).
In numbers3 := numbers[1:5]
, the result will have a capacity of 7
, because the first element in the result is at index 1
, so 8 - 1 = 7
.
In numbers4 := numbers[3:8]
, the capacity will be 8 - 3 = 5
.
Note: This is when you use a "simple" slice expression, that is when you only provide 2 indices in the slice expression (which has the form of a[low : high]
). There is also a "full" slice expression which has the form of a[low : high : max]
, which additionally controls the resulting slice's capacity by setting it to max - low
.
See related questions:
https://stackoverflow.com/questions/36683911/go-slices-capacity-length/36689864#36689864
https://stackoverflow.com/questions/31685620/go-slice-length-is-capacity-1-why/31685840#31685840
https://stackoverflow.com/questions/33859066/slicing-out-of-bounds-error-in-go/33859638#33859638
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论