虽然 Golang 中很少直接使用数组,但由于 切片 slice
是 数组 arrays
的一种动态实现,所以讲解切片 slice
之前,很有必要先搞清楚 数组 arrays
如何实现。
数组 array
数组的声明
数组 arrays
就是一个 固定类型、固定长度
的序列。数组的语法如下:
var 变量名 [数组长度] 数组元素类型 // var a [2]int
数组中每个元素都能够通过 索引下标来访问
,索引下标从 0 开始 到 数组长度 - 1
,内置函数 len() 获得数组内元素个数(即:数组长度)。
数组初始化时每个元素的值默认为元素类型对应的零值
,也可以声明直接赋值
var b [3]int = [3]int{1, 2, 3}
如果出事化时不清楚数组长度,可以是用 ...
表示数组长度根据初始化时元素个数决定
c := [...]int{1, 2, 3}
切片 slices
切片 slice 作为一种引用类型指向底层的数组,是对数组中某个 连续片段的引用
。需要留意的是,终止索引下标值不包括在切片内。
相对于数组的固定类型、固定长度
,Slice 可以动态增长、变短,功能相对更灵活
切片的声明
从数组、切片的连续内存生成切片是常有操作,切片语法如下:
slice[开始位置 : 结束位置] // slice 被切片变量
注意:终止索引下标值不包括在切片内,举个例子:
切片的容量上限
创建切片 Slice
也会经常用到内建函数 make,语法如下:
func make([]Type, len, cap) []Type
需要注意的是第 3 个可选参数
的容量上限。
- 不指定
容量上限 cap
的话,默认会和原数组长度 len 相同。 - 指定容量上限,切片后不能通过 slices[:cap(slices)] 访问原数组内容
- cap 为切片
第一个元素
在原数组的索引值
与原数组长度
的差值的绝对值
s := make([]int, 5),`切片 s` 长度为 5,容量上限 5。
s2 := s[1:3]
复制代码
切片时 golang 会新建一个 切片 s2
,底层的引用数据不动
。s2 通过更改指针指向、长度、容量来进行切片。这也是切片性能非常高的原因。
一个切片不能越过容量上限 cap 进行操作,因为从指针的角度,这就是越界进行非法访问。
切片追加元素
Golang 的内建函数 append() 可以给切片动态追加元素, 当切片的容量上限不够容纳元素是,切片会自动进行扩容
,此时切片长度会被改变。
切片扩容时,容量上限是有规律地按容量上限的 2 倍
(1、2、4、8)进行扩充,并将之前的元素复制进去。下面测试了下:
如果要追加一个 slice 到另一个 slice 的话,这样:
切片复制
Golang 的内置函数 copy() 可以复制数组切片,使用语法如下:
copy(number1,number2) //拷贝 number2 的内容到 number1
需要注意的是:如果复制时两个切片容量上限并不一致,会按照容量上限较小
的数组切片的容量上限
进行复制。