为什么cap不打印基础数组的长度?

时间:2019-06-28 11:23:28

标签: arrays go slice

我正在阅读Slice length and capacity部分中的“ GO旅游”,我运行了示例:

package main

import "fmt"

func main() {
    s := []int{2, 3, 5, 7, 11, 13}
    printSlice(s)

    // Slice the slice to give it zero length.
    s = s[:0]
    printSlice(s)

    // Extend its length.
    s = s[:4]
    printSlice(s)

    // Drop its first two values.
    s = s[2:]
    printSlice(s)
}

func printSlice(s []int) {
    fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

构建并运行该应用程序时,它的打印内容如下:

len=6 cap=6 [2 3 5 7 11 13]
len=0 cap=6 []
len=4 cap=6 [2 3 5 7]
len=2 cap=4 [5 7]

在Go文档中, cap 是基础数组的长度,为什么它的值不是6?

2 个答案:

答案 0 :(得分:9)

  

在Go文档中, cap 是基础数组的长度,为什么它的值不是6?

因为容量不是(不是后备阵列的大小)(在某些情况下,当它们相等时可能会出现特殊情况,但通常情况下并非如此)。通过切片支持数组来创建切片时,将0用于低索引(或省略),将数组长度用于高索引(或省略),则是,容量等于数组的长度。

Spec: Length and capacity:

  

切片的容量是在基础数组中为其分配了空间的元素数。

因此,容量从切片的第一个元素开始,如果与后备数组的第一个元素不同,则它们将不相等。您链接的Tour page中也明确指出了这一点:

  

切片的容量是基础数组中元素的数量,从切片中的第一个元素开始计数

还有一个full slice expression,其形式为:

a[low : high : max]

在可以控制所得切片的容量的位置,可以限制将来的切片可以扩展切片的范围。 max索引可以指向数组的最后一个元素之前

请参见以下示例:

a := [10]int{}

s := a[:] // len=10, cap=10
fmt.Printf("len=%d, cap=%d\n", len(s), cap(s))

s = a[2:] // len=8, cap=8
fmt.Printf("len=%d, cap=%d\n", len(s), cap(s))

s = a[2:7] // len=5, cap=8
fmt.Printf("len=%d, cap=%d\n", len(s), cap(s))

s = a[2:7:8] // len=5, cap=6
fmt.Printf("len=%d, cap=%d\n", len(s), cap(s))

输出(在Go Playground上尝试):

len=10, cap=10
len=8, cap=8
len=5, cap=8
len=5, cap=6

答案 1 :(得分:1)

当您删除两个第一个值时,您只剩下基础数组中剩下的最后4个项目。

[2 3 5 7 11 13]

执行s = [:0]时,切片的长度为0,上限为6:[]2 3 5 7 11 13

执行s = [:4]时,切片的长度为4,上限为6:[2 3 5 7] 11 13

执行s = [2:]时,切片的长度为2,上限为4:2 3 [5 7] 11 13

这是因为该数组不再可以访问前两个值,而如果扩展切片的长度,则仍可以访问后两个值。