切片

切片组成要素:

  • 指针:指向底层数组
  • 长度:切片中元素的长度,不能大于容量
  • 容量:指针所指向的底层数组的总容量

常见初始化方式

  • 使用 make 初始化
  1. slice := make([]int, 5) // 初始化长度和容量都为 5 的切片
  2. slice := make([]int, 5, 10) // 初始化长度为 5, 容量为 10 的切片
  • 使用简短定义
  1. slice := []int{1, 2, 3, 4, 5}
  • 使用数组来初始化切片
  1. arr := [5]int{1, 2, 3, 4, 5}
  2. slice := arr[0:3] // 左闭右开区间,最终切片为 [1,2,3]
  • 使用切片来初始化切片
  1. sliceA := []int{1, 2, 3, 4, 5}
  2. sliceB := sliceA[0:3] // 左闭右开区间,sliceB 最终为 [1,2,3]

长度和容量

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. slice := []int{1, 2, 3, 4, 5}
  7. fmt.Println("len: ", len(slice))
  8. fmt.Println("cap: ", cap(slice))
  9. //改变切片长度
  10. slice = append(slice, 6)
  11. fmt.Println("after append operation: ")
  12. fmt.Println("len: ", len(slice))
  13. fmt.Println("cap: ", cap(slice)) //注意,底层数组容量不够时,会重新分配数组空间,通常为两倍
  14. }

以上代码,预期输出如下:

  1. len: 5
  2. cap: 5
  3. after append operation:
  4. len: 6
  5. cap: 12

注意点

  • 多个切片共享一个底层数组的情况

对底层数组的修改,将影响上层多个切片的值

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. slice := []int{1, 2, 3, 4, 5}
  7. newSlice := slice[0:3]
  8. fmt.Println("before modifying underlying array:")
  9. fmt.Println("slice: ", slice)
  10. fmt.Println("newSlice: ", newSlice)
  11. fmt.Println()
  12. newSlice[0] = 6
  13. fmt.Println("after modifying underlying array:")
  14. fmt.Println("slice: ", slice)
  15. fmt.Println("newSlice: ", newSlice)
  16. }

以上代码预期输出如下:

  1. before modify underlying array:
  2. slice: [1 2 3 4 5]
  3. newSlice: [1 2 3]
  4. after modify underlying array:
  5. slice: [6 2 3 4 5]
  6. newSlice: [6 2 3]
  • 使用 copy 方法可以避免共享同一个底层数组

示例代码如下:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. slice := []int{1, 2, 3, 4, 5}
  7. newSlice := make([]int, len(slice))
  8. copy(newSlice, slice)
  9. fmt.Println("before modifying underlying array:")
  10. fmt.Println("slice: ", slice)
  11. fmt.Println("newSlice: ", newSlice)
  12. fmt.Println()
  13. newSlice[0] = 6
  14. fmt.Println("after modifying underlying array:")
  15. fmt.Println("slice: ", slice)
  16. fmt.Println("newSlice: ", newSlice)
  17. }

以上代码预期输出如下:

  1. before modifying underlying array:
  2. slice: [1 2 3 4 5]
  3. newSlice: [1 2 3 4 5]
  4. after modifying underlying array:
  5. slice: [1 2 3 4 5]
  6. newSlice: [6 2 3 4 5]

小练习

如何使用 copy 函数进行切片部分拷贝?

  1. // 假设切片 slice 如下:
  2. slice := []int{1, 2, 3, 4, 5}
  3. // 如何使用 copy 创建切片 newSlice, 该切片值为 [2, 3, 4]
  4. newSlice = copy(?,?)