【问题标题】:How does the slices behave when their capacity reduce?当容量减少时,切片的行为如何?
【发布时间】:2017-07-01 15:48:27
【问题描述】:

我已经阅读了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

我想知道这有什么意义?有没有像增加这样的容量计算公式的正确方法?

【问题讨论】:

    标签: arrays go slice


    【解决方案1】:

    切片规则见Spec: Slice expressions

    在您的示例中,numbersarray。当您对数组进行切片时,结果切片的容量将是从结果切片的第一个元素到数组的最后一个元素的元素数。当您对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

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

    查看相关问题:

    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?

    【讨论】:

    • 感谢您的解释和其他相关的现有问题。
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 2017-03-18
    • 1970-01-01
    • 1970-01-01
    • 2019-11-02
    • 1970-01-01
    • 2021-01-18
    相关资源
    最近更新 更多