说明
切片(Slice)
是go
提供的一种便捷操作数组的数据结构。可以按需自动增长和缩小数组,切片通过append
函数来动态添加底层数组数据。因为切片的底层是数组,所以在内存中是在连续内存块中分配内存的,所以切片可以和数组一样获得索引,迭代以及垃圾回收优化等好处。
声明切片
make声明切片
// 声明切片 容量为4 类型int初始化默认值为0 slice:=make([]int,4) fmt.Println(slice) // 输出 [0 0 0 0]
网络异常,图片无法展示
|
切片字面量
如果在
[]
运算符里指定了一个值,那么创建的就不是切片,而是数组。只有不指定值的时候才会创建切片
// 创建一个容量为4的切片,并赋初始值 slice:=[]int{1,2,3,4} fmt.Println(slice) // 输出 [1 2 3 4]
网络异常,图片无法展示
|
nil
切片
// 声明nil切片 此时不会初始化默认值 var slice []int fmt.Println(slice) // 输出 []
空切片
// 空切片 没有初始化默认值 slice:=[]int{} fmt.Println(slice) // 输出 []
网络异常,图片无法展示
|
两个切片共用一个底层数据
修改数据操作
- 声明两个切片共用一个底层数组
slice2 := slice[1:3]可以看成slice2 := slice[x:y],因为slice底层数组容量为4,
所以slice2的长度为:y-x(3-1=2)。容量为:4-x(4-1=3)
slice := []int{1,2,3,4} slice2 := slice[1:3] fmt.Println(slice) fmt.Println(slice2) // 输出 [1 2 3 4] [2 3]
网络异常,图片无法展示
|
- 修改slice2切片的数据
同时也修改了slice的值
slice2[1] = 99 fmt.Println(slice) fmt.Println(slice2) // 输出 [1 2 99 4] [2 99]
-
网络异常,图片无法展示|
添加数据操作
在上面数据基础上添加一个数据到slice2
同时会修改slice的值,因为底层数组是同一个
slice2 = append(slice2,66) fmt.Println(slice) fmt.Println(slice2) // 输出 [1 2 99 66] [2 99 66]
网络异常,图片无法展示
|
### 使添加操作不影响原切片
解决这个问题就是在赋值时使用切片字面量的第三个参数
**slice2 := slice[1:2:2] 可以看成slice2 := slice[x:y:z] **因为slice底层数组容量为4,
所以slice2的长度为:y-x(2-1=1), slice2的容量为:z-x(2-1=1)
slice := []int{1,2,3,4} //slice2 := slice[1:3] // 设置限制容量为2-1=1 slice2 := slice[1:2:2] // 添加参数slice2将进行扩容 扩容到原来的2倍 slice2 = append(slice2,66) fmt.Println(slice) fmt.Println(slice2) // 输出 [1 2 3 4] [2 66]
网络异常,图片无法展示
|
扩容
在切片容量小于1000个元素时,总是会成倍地增加容量,一旦元素超过1000,容量的增长因子会设为1.25,也就是会每次增加25%的容量。随着go
不断的迭代更新,这种增长算法可能会有所改变。
slice := []int{1,2,3,4} fmt.Printf("扩容前容量:%d\n",cap(slice)) fmt.Println("内容:",slice) fmt.Println("------------------------") slice = append(slice,88) fmt.Printf("扩容后容量:%d\n",cap(slice)) fmt.Println("内容:",slice) // 输出 扩容前容量:4 内容: [1 2 3 4] ------------------------ 扩容后容量:8 内容: [1 2 3 4 88]
网络异常,图片无法展示
|