切片 a、b、c 的长度和容量分别是多少?

package main

import (
    "fmt"
)

func main() {
    s := [3]int{1, 2, 3}
    a := s[:0]
    b := s[:2]
    c := s[1:2:cap(s)]

    fmt.Println(len(a), cap(a))
    fmt.Println(len(b), cap(b))
    fmt.Println(len(c), cap(c))
}

a 长度和容量 0 3 b 长度和容量 2 3 c 长度和容量 1 2

在线运行

知识点:数组或切片的截取操作

截取操作有带 2 个或者 3 个参数,形如:[i:j][i:j:k]

1. [i:j] 形式

[i:j] 是最常见的切片截取形式,表示从底层数组的第 i 个元素开始,到第 j 个元素(不包括第 j 个元素)结束。

  • 语法s[i:j]
  • 含义
    • i:切片的起始索引(包含)。
    • j:切片的结束索引(不包含)。
  • 长度j - i
  • 容量:从索引 i 开始,到底层数组的末尾。
    • 如果底层数组的长度为 n,则容量为 n - i

示例

s := [3]int{1, 2, 3}
b := s[:2] // 从索引 0 开始,到索引 3(不包含)左闭右开
fmt.Println(a)       // 输出: [1 2]
fmt.Println(len(a))  // 输出: 2 (长度) 2-0
fmt.Println(cap(a))  // 输出: 3 (容量,因为底层数组长度为 3,从索引 0 开始) 3-0

2. [i:j:k] 形式

[i:j:k] 是更灵活的切片截取形式,除了指定切片的起始和结束索引外,还可以显式指定切片的容量。

  • 语法s[i:j:k]
  • 含义
    • i:切片的起始索引(包含)。
    • j:切片的结束索引(不包含)。
    • k:切片的容量截止索引(不包含)。
  • 长度j - i
  • 容量k - i
    • 容量不能超过底层数组的长度,否则会引发运行时错误。

示例

s := [3]int{1, 2, 3}
c := s[1:2:cap(s)] // 从索引 1 开始,到索引 2(不包含),容量截止到索引 3
fmt.Println(c)       // 输出: [2]
fmt.Println(len(c))  // 输出: 1 (长度,2 - 1 = 1)
fmt.Println(cap(c))  // 输出: 2 (容量,3 - 1 = 2)