1. 定义
在Go语言中切片是一种数据结构,很便于使用和管理数据集合。切片是围绕动态数组的概念构建的,可以按需自动增长和缩小。切片的动态增长是通过内置函数append来实现的。这个函数可以快速且高效地增长切片。还可以通过对切片再次切片来缩小一个切片的大小。因为切片的底层内存也是在连续块中分配的,所以切片还能获得在访问速度以及垃圾回收优化等方面的好处。
切片在Go语言的源码定义如下所示,由于其数据结构中有指向底层数组的指针,所以切片是一种引用类型。
// src/runtime/slice.go
type slice struct {
array unsafe.Pointer
len int
cap int
}
2. 内部实现
切片是一个很小的对象,对底层数组进行了抽象。切片的数据结构有3个字段,分别是指向底层数组的指针array,切片中元素的个数len(即长度)和切片的最大容量cap。如下图所示。
3. 切片的创建
(1) 由数组创建
创建语法为array[b:e], 其中array表示数组名;b表示索引开始位,可以不指定,默认为0;e表示索引结束位,可以不指定,默认是len(array),[b:e]区间是“左闭右开”,即第一个元素是array[b],最后一个元素是array[e-1]。例如:
// 创建有7个int类型元素的数组
var array = [...] int{0,1,2,3,4,5,6}
s1 := array[0:4]
s2 := array[:4]
s3 := array[2:]
fmt.Println(s1) // [0 1 2 3]
fmt.Println(s2) // [0 1 2 3]
fmt.Println(s3) // [2 3 4 5 6]
(2) 通过内置函数make创建切片
切片使用之前需要make是因为make操作要完成切片底层数组的创建及初始化,由make创建的切片个元素被默认初始化位切片元素类型的默认值。例如:
// len = 10, cap = 10
a := make([]int, 10)
// len = 10, cqp = 15
b := make([]int, 10, 15)
fmt.Println(a) // 结果为 [0 0 0 0 0 0 0