Go语言中切片的内部实现和基础功能
切片是一种数据结构,这种数据结构便于使用和管理数据集合。切片是围绕动态数组的概念构建的,可以按需自动增长和缩小。切片的动态增长是通过内置函数append来实现的。这个函数可以快速且高效的增长切片。还可以通过对切片再次切片来缩小切片的大小。因为切片的底层内存也是在连续块中分配的,所以切片还能获得索引、迭代以及垃圾回收优化的好处。
内部实现
切片是一个很小的对象,对底层数组进行了抽象,并提供相关的操作方法。切片有3个字段的数据结构,这些数据结构包含Go语言需要操作底层数组的元数据。
这3个字段分别是指向底层数组的指针、切片访问的元素的个数(即长度)和切片允许增长到的元素个数(即容量)。
创建和初始化
- make和切片字面量
一种创建切片的方法是使用内置的make函数。当使用make时,需要传入一个参数,指定切片的长度:
slice := make([]string, 5)
如果只指定长度,那么切片的容量和长度相等。也可以分别指定长度和容量:
slice := make([]int, 3, 5)
分别指定长度和容量时,创建的切片,底层数组的长度是指定的容量,但是初始化后并不能访问所有的数组元素。
通过切片字面量来声明切片
slice := []string{"Red","Blue","Green","Yello","Pink"}
使用索引声明切片
slice := []string{99:""}
声明数组和声明切片的不同
array := [3]int{10,20,30}
slice := []int{10,20,30}
- nil和空切片
创建nil切片
var slice []int
声明空切片
slice := make([]int, 0)
slice := []int{}
使用切片
- 赋值和切片
对切片里某个索引指向的元素赋值和对数组里某个索引指向的元素赋值的方法完全一样。使用[]
操作符就可以改变某个元素的值。
slice := []int{10,20,30,40,50}
slice[1] = 25
使用切片创建切片
slice := []int{10,20,30,40,50}
newSlice := slice[1:3]
- 切片增长
相对于数组而言,使用切片的一个好处是,可以按需增加切片的容量。Go语言内置的append函数会处理增加长度时的所有操作细节。
要使用append,需要一个被操作的切片和一个要追加的值:
slice := []int{10,20,30,40,50}
newSlice := slice[1:3]
newSlice = append(newSlice, 60)