Go切片
切片
-
概念
- 与数组类似,也叫做变长数组或动态数组
- 是引用类型,因为它指向一个底层的数组
-
语法
-
定义切片
var slicename []type //不需要说明切片的长度 var slicename = []int{1,2,3} //直接初始化
使用make创建切片
func make(Type, size ...IntegerType) Type 1.内建函数make分配并初始化一个类型为切片、映射、或通道的对象 2.第一个实参为类型 3.第二个参数为长度,实际存储元素的数量,只有在长度的范围内才会初始化零值 4.第三个参数为容量,容量是指最多能存储多少个数据 5.长度必须<=容量 6.通过下标只能读写长度范围内的数据 7.只能通过append向切片追加数据 var silename = make([]int,3,5)
func append(slice []Type, elems ...Type) []Type 1.内建函数append将元素追加到切片的末尾。 2.若它有足够的容量,就在末尾追加数据。 3.否则,就会分配一个新的基本数组(成倍数的扩充容量,) append可以将一个切片追加到另一个切片里,但是不能使用append(slice1,slice2)的形式,因为slice2是个切片,append函数要求只能是type元素,所以合法的写法是append(slice1,slice2...) func append(slice []Type,otherSlice... []Type) []Type
从已有数组上直接创建切片
//array直接就是slice的底层数组 array := [...]int{1,2,3} slice := array[start:end] //左闭右开, array[start]~array[end-1] slice := array[start:] //array[start]~最后一个元素 slice := array[:end] //第一个元素~array[end-1] slice := array[:] //全部的array元素 切片长度: 切片对应数组片段的长度 切片容量: 切片第一个元素在数组中的起始位置到数组最后一个元素的长度
-
遍历切片
for i := 0 ; i < len(slice) ;i++ {} for index,value := range slice {}
-
-
内存分析
- 切片是引用类型的数据,也就是数据里存储的内存地址
- slice创建的过程
- 先创建底层数组
- 把数组地址赋值给切片变量
- 因为slice是引用类型,存储的数组地址,所以可以直接使用%p占位符打印
- 切片的地址也就是引用的数组的第一个切片元素的地址
- 每一个切片引用一个底层数组
- 切片本身不存储任何数据,都是底层数组存储数据,所以修改切片也就是修改这个数组中的数据
- 当向切片添加数据时,如果没有超过容量就直接添加,如果超过容量就自动创建一个扩容底层数组。
扩容的规则是:如果扩容到2倍cap满足就扩容到2倍,否则就扩容到2*cap< len < 最小的2n - 切片一旦扩容,就重新指向一个新的底层数组
-
修改底层数组
- 因为所有的切片变量指向同一个底层数组,所以修改底层数组数据,所有的切片都能看到
- 同样道理,通过切片修改元素,底层数组和其他指向同一底层数组的切片,也都能看到
- 通过append修改切片,实质也是在切片的底层数组指定位置追加或覆盖数据,在不扩容的情况下,底层数组或其他切片变量也能看到;如果发生了扩容,执行了append函数的切片更换了底层数组,旧底层数组和其他切片不会看到追加数据
-
数据类型小结
按照类型来分:
基本类型:int,float ,string ,bool
复合类型:array, slice ,map , struct ,pointer , function, chan
按照特点来分:
值类型:int ,float,string,bool,array
传递的是数据的副本
引用类型:Slice
传递地址,多个变量指向同一块内存地址