go 切片

在 Go 语言中,切片(slice)是一个非常重要的数据结构,它是对数组的抽象,提供了更灵活、更强大的序列操作能力。切片本身并不存储任何数据,它只是对底层数组的引用,提供了访问数组部分或全部元素的能力。

切片的定义

切片由三个部分组成:

  1. 指针:指向底层数组中切片开始的元素。
  2. 长度(length):切片中元素的数量。
  3. 容量(capacity):从切片的起始位置到底层数组末尾的元素数量。

创建切片

  1. 通过数组创建切片
    arr := [5]int{1, 2, 3, 4, 5}
    slice := arr[1:4] // 创建一个包含 arr[1], arr[2], arr[3] 的切片
    fmt.Println(slice) // 输出: [2 3 4]
  2. 直接创建切片
    slice := []int{1, 2, 3, 4, 5}
    fmt.Println(slice) // 输出: [1 2 3 4 5]
  3. 使用 make 函数创建切片
    slice := make([]int, 5) // 创建一个长度为5,容量为5的切片
    fmt.Println(slice) // 输出: [0 0 0 0 0]

切片的操作

  1. 访问元素
    slice := []int{1, 2, 3, 4, 5}
    fmt.Println(slice[2]) // 输出: 3
  2. 修改元素
    slice := []int{1, 2, 3, 4, 5}
    slice[2] = 10
    fmt.Println(slice) // 输出: [1 2 10 4 5]
  3. 追加元素
    slice := []int{1, 2, 3}
    slice = append(slice, 4, 5)
    fmt.Println(slice) // 输出: [1 2 3 4 5]
  4. 切片的切片
    slice := []int{1, 2, 3, 4, 5}
    subSlice := slice[1:3]
    fmt.Println(subSlice) // 输出: [2 3]
  5. 切片的长度和容量
    slice := []int{1, 2, 3, 4, 5}
    fmt.Println(len(slice)) // 输出: 5
    fmt.Println(cap(slice)) // 输出: 5
  6. 复制切片
    slice1 := []int{1, 2, 3}
    slice2 := make([]int, len(slice1))
    copy(slice2, slice1)
    fmt.Println(slice2) // 输出: [1 2 3]

切片的底层数组

切片是对底层数组的引用,因此对切片的修改会影响底层数组,反之亦然。

arr := [5]int{1, 2, 3, 4, 5}
slice := arr[1:4]
slice[0] = 10
fmt.Println(arr) // 输出: [1 10 3 4 5]

切片的扩容

当切片的容量不足以容纳新元素时,Go 会自动为其分配一个新的底层数组,并将原有元素复制到新数组中。

slice := []int{1, 2, 3}
slice = append(slice, 4, 5, 6)
fmt.Println(slice) // 输出: [1 2 3 4 5 6]

注意事项

  • 切片是引用类型,传递切片时不会复制底层数组,而是共享同一个底层数组。
  • 切片的零值是 nil,表示一个空的切片。

总结

切片是 Go 语言中非常强大且灵活的工具,它提供了对数组的动态视图,使得操作数组变得更加方便。理解切片的底层机制对于编写高效的 Go 代码非常重要。

Posted in Go