首页 > 解决方案 > 为什么 cap 不打印底层数组的长度?

问题描述

我正在阅读 A Tour of 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 文档中,上限是底层数组的长度,为什么它的值不是 6?

标签: arraysgoslice

解决方案


在 Go 文档中,上限是底层数组的长度,为什么它的值不是 6?

因为容量不是后备数组的大小(可能有特殊情况相等,但一般情况下不相等)。当通过切片支持数组创建切片时,使用0低索引(或省略它)和高索引的数组长度(或省略它),那么是的,容量将等于数组的长度。

规格:长度和容量:

切片的容量是在底层数组中分配空间的元素的数量。

所以容量从切片的第一个元素开始,如果它与后备数组的第一个元素不同,它们将不相等。您链接的游览页面中也明确说明了这一点:

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

还有一个完整的切片表达式,其形式为:

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

推荐阅读