2026-10-17 12:15:25
Go语言中的切片(slice)是一种动态数组,它提供了比数组更灵活、高效的数据处理能力。以下是关于切片原理与用法的详细说明:
一、什么是切片切片是对数组的一个连续片段的引用,其本质是一个三元组:
从数组或切片派生:
arr := [5]int{1, 2, 3, 4, 5}s1 := arr[1:4] // 包含索引1到3,不包含4fmt.Println(s1) // [2 3 4]使用make:
s2 := make([]int, 3, 5) // 长度为3,容量为5fmt.Println(s2) // [0 0 0]使用字面量:
s3 := []string{"go", "java", "rust"}访问元素:
s := []int{10, 20, 30}fmt.Println(s[1]) // 20修改元素:
s[1] = 99遍历切片:
for i, v := range s { fmt.Printf("Index %d: %dn", i, v)}当切片容量不足时,使用append会自动扩容:
s := []int{1, 2}s = append(s, 3, 4, 5)fmt.Println(s) // [1 2 3 4 5]注意:append可能导致切片指向新的底层数组。
六、切片之间的共享与副本多个切片可能共享同一个底层数组:
arr := [5]int{1, 2, 3, 4, 5}s1 := arr[1:4]s2 := arr[2:5]s1[1] = 99fmt.Println(arr) // [1 2 99 4 5]fmt.Println(s2) // [99 4 5]如果需要独立副本,可使用copy:
dst := make([]int, len(s1))copy(dst, s1)七、切片是引用类型函数传参时,修改切片会影响原始数据(因为底层数组是共享的):
func modify(s []int) { s[0] = 100}a := []int{1, 2, 3}modify(a)fmt.Println(a) // [100 2 3]八、删除切片元素Go没有内建删除函数,可以用切片拼接模拟:
s := []int{1, 2, 3, 4, 5}i := 2 // 删除索引为2的元素s = append(s[:i], s[i+1:]...)fmt.Println(s) // [1 2 4 5]九、切片陷阱:共享底层数组导致意外修改s1 := []int{1, 2, 3, 4}s2 := s1[:2]s3 := append(s2, 99, 100) // 此时可能会影响 s1 的内容使用copy()复制切片是解决此问题的安全做法。
十、小结动态长度:可根据需要自动扩容。
引用类型:多个切片可能共享底层数组。
三元结构:指针 + 长度 + 容量。
切片的灵活性和效率让它成为Go语言中处理数据集合的首选结构。理解其底层原理能帮助你写出更高性能的代码。