在保持其子切片的同时生长切片

Growing a slice while keeping its subslice around

我一直在尝试切片。这是一个示例程序

for n := 1; n <= 10; n++ {
    a := make([]int, 0)
    for j := 0; j < n; j++ {
        a = append(a, 0)
    }
    b := a[:1]
    a = append(a, 0)
    a[0] = 1
    fmt.Println(n, b[0])
}

输出为

1 0
2 0
3 1
4 0
5 1
6 1
7 1
8 0
9 1
10 1

我明白这里发生了什么。如果旧数组长度不足,a = append(a, 0)行分配一个新数组,新数组的长度是原来的两倍。因此,如果 n 是 2 的幂,则行

a[0] = 1

不会更改 b 支持的数组,因为新数组将在之前的行中分配。

但是我在文档中找不到明确的声明新分配的数组总是有两倍的长度。这是否意味着我的代码依赖于实现?以这种方式将另一个切片的切片存储在变量中是不好的做法,还是每次需要子切片时我都应该做 a[j:k]

基础数组的大小加倍是一个实现细节(在当前实现中,一旦大小达到某个阈值就不再适用)。所以你不能依靠这个来有选择地改变b[0]或不改变。

很遗憾,我不明白你最后两个问题。子切片没有任何问题,它不依赖于显式 (a[i:k]) 或隐式开始或停止索引 (a[i:]a[:k]),因为这是完全相同的。

你已经知道答案了。

  • 它取决于实现
  • 如果您要更改基础 array/slice
  • ,则将子切片分片到 var 是不好的做法
  • 你最好在需要的时候显式地使用子切片——它很便宜。

问得好。感谢分享。