今天我们来学习一下Go语言中的切片和它的基本使用。
话外音
因为数组的长度是固定的且数组长度属于类型的一部分,因此数组在使用的过程中有很多的局限限。比如:
func arraySum(x [3]int) int{
sum := 0
for _, v := range x{
sum = sum + v
}
return sum
}
这个数组求和的函数只能接收[3]int
类型,其他的都不支持。再比如:
a := [3]int{1, 2, 3}
数组中已经有三个元素了,就不能继续添加新元素了。
简介
切片是拥有相同元素可变长度的序列,它是基于数组类型做的一层封装。它比数组要更加的灵活,支持自动扩容。切片是引用类型,它的内部结构包含地址
、长度
和容量
。切片一般用户快速操作一块数据的集合。
定义
语法如下下:
var name []T
说明:
name
- 变量名T
- 元素的类型
小示例:
func main() {
var a []int
var b = []int{}
var c = []bool{false, true}
var d = []bool{false, true}
fmt.Println(a) // []
fmt.Println(b) // []
fmt.Println(c) // [false true]
fmt.Println(d) // [false true]
fmt.Println(a == nil) // true
fmt.Println(b == nil) // false
fmt.Println(c == nil) // false
//fmt.Println(c == d) // 切片是引用类型,不支持直接比较,只能和nil比较
}
长度和容量
切片拥有自己的长度和容量,可以通过内置的len()
求它的长度,通过内置的cap()
求它的容量。注意:长度和容量并不是一个东西。
切片表达式
切片表达式是从字符串、数组、指向数组或切片的指针构造子字符串或切片。它有两种变体:一种指定low
和high
两个索引界限值的简单的形式,另一种是除了low
和high
索引界限值外还指定容量的完整的形式。
简单的切片表达式
切片的底层就是一个数组,因为我们可以基于数组使用切片表达式的方式得到切片。切片表达式中的low
和high
表示索引范围(左包含,右不包含),示例如下:
func main() {
e := [5]int{0, 1, 2, 3, 4}
f := e[1:3]
fmt.Println(e)
fmt.Println(f)
fmt.Printf("f:%v len:%v cap:%v\n", f, len(f), cap(f))
}
输出:
f:[2 3] len:2 cap:4
为了方便起见,切片表达式中的索引还可以省略,如下:
a[2:] // 等同于a[2:len(a)]
a[:2] // 等同于a[0:2]
a[:] // 等同于a[0:len(a)]
使用make()函数构造切片
上面都是基于数据构造切片的,其实如果想动态生成切片,我们可以使用 mark()
函数,语法如下:
make([]T, size, cap)
说明:
T
- 切片的元素类型size
- 切片的元素数量cap
- 切片的容量
小示例:
func main() {
a := make([]int, 3, 6)
fmt.Println(a) // [0 0 0]
fmt.Println(len(a)) // 3
fmt.Println(cap(a)) // 6
}
判断切片是否为空
判断切片是否为空,只能使用 len(a) == 0
来判断,不能使用 a == nil
来判断。
切片赋值拷贝
切片拷贝前台的两个变量是共享底层数据的,因为修改其中一个切片的值,另一个切片的值也会被修改,如下:
func main() {
a := []int{1, 2, 3}
b := a
fmt.Println(a, b) // [1 2 3] [1 2 3]
b[0] = 100 // 修改b切片值
fmt.Println(a, b) // [100 2 3] [100 2 3]
}
切片拷贝还可以使用 copy()
函数,不同的是该函数拷贝出来的空间是独立的,如下:
func main() {
a := []int{1, 2, 3}
b := make([]int, 3, 3)
copy(b, a)
fmt.Println(a, b) // [1 2 3] [1 2 3]
b[0] = 100 // 修改b切片值
fmt.Println(a, b) // [1 2 3] [100 2 3]
}
切片添加元素
可以通过内建函数 append()
为切片添加元素,可以一次添加一个元素,可以添加多个元素,也可以添加另一个切片中的元素(后面加…),如下:
func main() {
a := []int{1, 2}
a = append(a, 3, 4)
fmt.Println(a) // [1 2 3 4]
b := []int{5, 6}
a = append(a, b...)
fmt.Println(a) // [1 2 3 4 5 6]
}
切片怎么删除元素呢?抱歉,木月内置函数,自己想办法!!!