golang 切片
Golang切片
golang中的切片是一种数据结构,这种数据结构便于使用和管理数据集合。切片可以认为是动态数组,其大小可以按需动态的增大或者缩小。
如果我们想扩充一个切片,可以使用append
内置函数向切片中添加值
如果我们想缩小一个切片,那么我们可以使用再切片
的方式,对切片再次进行切片即可
内部实现
切片是一个很小的对象,对底层的数组进行了抽象,并且提供了相应的操作方法。切片主要有三个字段:指向底层数组的指针
, 切片访问元素的个数
, 切片允许增长到的元素个数
创建和初始化
1. 使用make函数
// 在不指定容量的时候,长度和容量一致,也就是说下面的
// 代码中,slice的长度为3,同时容量也为3
slice := make([]int, 3)
// 可以分别指定长度和容量
// 但是必须保证容量 >= 长度,否则编译不通过
slice2 := make([]int, 3, 5)
2. 通过切片字面量
// 注意[]中不能含有数值,否则声明不是切片而是数组
// 下面声明的切片中长度和容量均为3
slice := []int{1, 2, 3}
// 可以声明自定义长度的切片
// 下面的99就表示索引
slice2 := []int{99:1}
3. nil切片和空切片
如果只声明一个切片类型的数据,那么这个变量就是一个nil切片
var slice []int
如果使用slice==nil进行判断,会返回true
⭐️在描述一个不存在的切片的时候,nil切片比较好用,比如说函数要求返回一个切片,但是发生异常的时候
如果对一个切片类型的数据进行初始化,可以获取一个空切片
// 使用make函数来声明
slice := make([]int, 0)
// 使用切片字面量创建
slice := []int{}
⭐️在表示一个空集合的时候,空切片更合适。比如在数据查询的时候,返回0条记录, 在json序列化的时候使用空切片会生成[],但是如果是nil切片则为null
对于nil切片和空切片,使用append, len, cap 函数的效果都是一样的,但是在使用上还是略有区别,可以参考https://www.meirixz.com/archives/80658.html
切片的使用
1. 赋值和切片
声明一个切片之后,如果我们需要修改一个切片内部的值,只需要类似于数组进行操作即可。
// 创建一个长度和容量均为3的切片
slice := []int{1, 2, 3}
// 修改索引为2对应数据的值
slice[2] = 10
// slice变成 1 2 10
使用切片创建切片
slice := []int{1, 2, 3, 4, 5}
// 进行切片,slice[start:end],不会取到end对应的值
// 如果需要取得最后一个数据,可以不指定end,直接使用slice[start:]
slice2 := slice[1:3]
通过切片创建的切片共享的是同一个底层数组,如果修改slice2,那么slice中的数据也会同样进行改变
如果我们只需要切片的一小部分,其余的部分都不再需要了,采用这种方式需要浪费很大的内存,可以参考https://blog.csdn.net/weixin_44676081/article/details/108291799
切片的时候还可以指定切片的容量,这时候需要三个索引
slice := []int{1, 2, 3, 4, 5}
// 此时slice2的长度为2,容量为3
// 但是注意容量不能超过可用容量
// 可用容量也就是原来切片的总容量减去start
slice2 := slice[1:3:4]
计算方式: slice[i:j:k], 那么长度为j-i,容量为k-i
2. 往切片中添加数据
使用内置函数append
可以向指定的切片中加入数据
slice := []int{1, 2, 3}
slice = append(slice, 4)
// 也可以一次添加多个
slice = append(slice, 4, 5)
如果容量到达极限,append函数可以自动为切片扩展空间
3. 访问切片
访问切片中的值有两种方式,一种是使用传统的for循环进行迭代,另一种使用range关键字进行访问
slice := []int{1, 2, 3, 4, 5, 6}
for i:=0; i< len(slice); i++{
fmt.Println(slice[i])
}
for index, value := range slice{
fmt.Printf("第%d个值为%d", index, value)
}
// 如果不需要索引,使用 _ 忽略即可
注意:
切片在作为函数的传递参数的时候,类似于C中的指针传参,会改变原来切片中的数据