- 一、切片的基本定义与声明
- 二、切片的底层结构
- 三、切片的切割操作
- 四、使用 make 创建切片(推荐方式)
- 五、切片的追加(append)
- 六、切片共享底层数组的副作用
- 七、使用
copy
复制切片,避免共享副作用 - 八、清空切片但保留容量(复用切片)
- 九、切片性能优化技巧
- 十、切片陷阱:内存泄漏风险
- 总结
切片是Go语言中最常用的数据结构之一,具有灵活、轻量的特点。本文将介绍切片的定义、底层原理、常用操作、性能优化技巧,并配套示例代码。
一、切片的基本定义与声明
切片是对数组的一个轻量级抽象,具有动态大小的特性。
示例 1:切片的定义与初始化
package main
import "fmt"
func main() {
s := []int{1, 2, 3}
fmt.Println(s) // 输出: [1 2 3]
}
二、切片的底层结构
切片的本质是一个结构体,包含:
- 一个指向底层数组的指针
- 长度(len)
- 容量(cap)
type slice struct {
ptr *T
len int
cap int
}
多个切片可能共享同一个底层数组。
三、切片的切割操作
你可以通过对已有数组或切片进行“切片”来创建新的切片。
示例 2:从数组切割出切片
package main
import "fmt"
func main() {
arr := [5]int{10, 20, 30, 40, 50}
s := arr[1:4] // 包含下标1至3,不含下标4
fmt.Println(s) // 输出: [20 30 40]
}
四、使用 make 创建切片(推荐方式)
使用 make
创建切片时,可以指定长度和容量,提高性能。
示例 3:使用 make 创建切片
s := make([]int, 3, 10)
fmt.Println(len(s), cap(s)) // 输出: 3 10
五、切片的追加(append)
Go 中切片的大小可变,可以使用 append
动态添加元素。
示例 4:追加元素
s := []int{1, 2}
s = append(s, 3, 4)
fmt.Println(s) // 输出: [1 2 3 4]
示例 5:自动扩容特性
s := []int{}
for i := 0; i < 10; i++ {
s = append(s, i)
}
fmt.Println(s) // 输出: [0 1 2 3 4 5 6 7 8 9]
六、切片共享底层数组的副作用
多个切片可能共享同一个数组,修改其中一个切片可能影响另一个。
示例 6:共享底层数组
a := []int{1, 2, 3, 4}
b := a[1:3]
b[0] = 99
fmt.Println(a) // 输出: [1 99 3 4]
七、使用 copy
复制切片,避免共享副作用
示例 7:用 copy
创建切片副本
src := []int{1, 2, 3}
dst := make([]int, len(src))
copy(dst, src)
dst[0] = 99
fmt.Println(src) // [1 2 3]
fmt.Println(dst) // [99 2 3]
八、清空切片但保留容量(复用切片)
可以使用 s = s[:0]
快速清空切片,适用于复用场景。
示例 8:复用切片空间
s := make([]int, 0, 100)
s = append(s, 1, 2, 3)
fmt.Println(s) // [1 2 3]
s = s[:0] // 清空但保留容量
fmt.Println(s) // []
fmt.Println(cap(s)) // 100
九、切片性能优化技巧
- 提前分配容量(避免频繁扩容)
s := make([]int, 0, 1000) // 高效方式
- 用
copy
避免共享副作用(如上) - 使用
s = s[:0]
实现复用
十、切片陷阱:内存泄漏风险
如果一个小切片引用了一个大的数组,可能导致整个大数组无法回收。
示例 9:避免切片内存泄漏
func subSliceSafe(s []byte) []byte {
tmp := make([]byte, len(s))
copy(tmp, s)
return tmp
}
总结
技巧 | 建议 |
---|---|
提前分配容量 | 使用 make([]T, 0, n) |
避免副作用 | 用 copy 创建独立副本 |
切片复用 | 使用 s = s[:0] 清空但不释放底层数组 |
避免内存泄漏 | 不要让小切片持有大数组,必要时手动 copy |

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
腾讯云开发者社区:孟斯特
—