Golang 语法速通指南(六)复合数据结构之切片(Slice)
本文重构于 Go 切片(Slice)
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,容量(cap)不够时会自动扩容
切片为引用类型,从数组中得到的切片修改元素值时,原数组也会发生变化,修改原数组时,切片也会变化
创建切片
创建切片可以有四种方法
使用 var
1 | var s []uint32 |
指定字面值
这样创建的切片长度和容量都等于初始元素个数
1 | s := []uint32{1, 2, 3} |
使用 make()
函数
可以指定长度和容量,格式为make([]type, len[, cap])
,可以只指定长度,也可以长度容量同时指定
1 | s1 := make([]uint32) |
使用截取符
可以从现成的数组或切片创建
1 | var arr [10]uint32 |
访问切片
- 直接使用下标
- 使用截取符
- 使用
for k,v:= range s
添加元素
使用append()
函数向切片中添加元素,可以一次添加 0 个或多个元素,如果容量不够会自动扩容
1 | s := make([]uint32, 0, 4) |
若要添加其他切片/数组或部分内容,可以使用下面方法
1 | s = append(s, s1...) |
修改元素
可以通过下标直接修改
注意,在你使用 for k,v:= range s
时,不能直接通过修改 v
来修改原切片,必须使用 s[k]
来修改(就像 Python 里面一样,你 range 出来的都是副本)
删除元素
截取需要的那部分再赋值回去就是删除
如果要删除中间的某个元素,可以使用下面的方法
1 | var s = []int{1, 2, 3, 4} |
拷贝
如果直接赋值,指向的底层数组是一样的,修改一个另一个也会跟着变
如果不想这样,可以使用 copy()
函数
此函数将内容从一个数组切片复制到另一个数组切片。如果加入的两个数组切片不一样大,就会按其中较小的那个数组切片的元素个数进行复制
1 | slice1 := []int{1, 2, 3, 4, 5} |
开发相关问题
如何比较两个切片
与数组不同,切片之间不能直接使用 ==
来比较(唯一的例外是和 nil
比较)
如果是 []byte
,可以使用标准库提供的高度优化的 bytes.Equal
函数来判断是否相等
对于其他类型,只能自己一个个枚举
1 | func equal(x, y []string) bool { |
判断切片为空
使用 len(s) == 0
来判断,而不应该用 s == nil
来判断
1 | var s []int // len(s) == 0, s == nil |
自动扩容的细节
还是有点复杂的,详情可以看这里