切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。
切片的本质就是对底层数组的封装,包含了三个信息:底层数组的指针、切片的长度和切片的容量
1.切片的定义
var a []string
var b =[]int{}
var c=[]bool{false,true}
fmt.Println(a,b,c) //[] [] [false true]
fmt.Println(a==nil) //true
fmt.Println(b==nil) //flase
2.切片的长度和容量
使用内置的len()函数求长度,使用内置的cap()函数求切片的容量
var array=[]bool{false,true}
fmt.Println(len(array))
fmt.Println(cap(array))
3.切片表达式
3.1简单切片表达式
a := [5]int{1,2,3,4,5}
s := a[0:3] //基于数组通过切片表达式得到切片
fmt.Println(cap(s))
fmt.Println(len(s))
a := [5]int{1,2,3,4,5}
s := a[3:4] //基于数组通过切片表达式得到切片
fmt.Println(cap(s)) //2
fmt.Println(len(s)) //1
3.2完整切片表达式
//a[low : high : max]
a := [5]int{1,2,3,4,5}
t := a[1:3:4]
fmt.Println(t) //2 3
fmt.Println(len(t)) //2
fmt.Println(cap(t)) //3
完整切片表达式需要满足的条件是0 <= low <= high <= max <= cap(a)
4.使用make()函数构造切片
基于数组来创建的切片,如果需要动态的创建一个切片,我们就需要使用内置的make()函数
make([]T, size, cap)
T:切片的元素类型
size:切片中元素的数量
cap:切片的容量
a := make([]int,2,10)
fmt.Println(a)
fmt.Println(len(a))
fmt.Println(cap(a))
5.判断切片是否为空
要检查切片是否为空,请始终使用len(s) == 0来判断,而不应该使用s == nil来判断。
var a1 []int
a2 := []int{}
a3 := make([]int,0)
fmt.Println(len(a1),cap(a1)) //0 0
fmt.Println(len(a2),cap(a2)) //0 0
fmt.Println(len(a3),cap(a3)) //0 0
fmt.Println(a1==nil) //true
fmt.Println(a2==nil) //false
fmt.Println(a3==nil) //false
array := make([]int,0)
fmt.Println(len(array)==0) //切片为空
6.切片的赋值拷贝
array := make([]int,3)
a := array //赋值后共用一个底层数组
a[0] =100
fmt.Println(array) //[100 0 0]
fmt.Println(a) //[100 0 0]
7.切片遍历
slice := []int{1,3,5}
for index,value := range slice {
fmt.Println(index,value)
}
fmt.Println("-------------------")
for i := range slice{
fmt.Println(i,slice[i])
}
8.添加元素
var slice []int
slice = append(slice,1)
slice = append(slice,2,3,4,5)
fmt.Println(slice)
slice := []int{1,2,3}
slice = append(slice,4,5,6)
fmt.Println(slice)
append()函数将元素追加到切片的最后并返回该切片。
切片的容量按照1,2,4,8,16这样的规则自动进行扩容,每次扩容后都是扩容前的2倍
append()函数还支持一次性追加多个元素
var slice []int
for i := 0; i < 10; i++ {
slice = append(slice,i)
fmt.Println(slice, len(slice), cap(slice))
}
输出结果:
[0] 1 1
[0 1] 2 2
[0 1 2] 3 4
[0 1 2 3] 4 4
[0 1 2 3 4] 5 8
[0 1 2 3 4 5] 6 8
[0 1 2 3 4 5 6] 7 8
[0 1 2 3 4 5 6 7] 8 8
[0 1 2 3 4 5 6 7 8] 9 16
[0 1 2 3 4 5 6 7 8 9] 10 16
9.复制切片
由于切片是引用类型,slice1和slice2其实都指向了同一块内存地址。修改slice2的同时slice1的值也会发生变化。
slice1 :=[]int{1,2,3,4,5}
slice2 := slice1
fmt.Println(slice1)
fmt.Println(slice2)
slice2[0] = 0
fmt.Println(slice1)
fmt.Println(slice2)
copy()函数可以迅速地将一个切片的数据复制到另外一个切片空间
slice1 :=[]int{1,2,3,4,5}
slice2 := make([]int,5,10)
copy(slice2,slice1)
fmt.Println(slice2) //[1 2 3 4 5]
slice2[0]=100
fmt.Println(slice1) //[1 2 3 4 5]
fmt.Println(slice2) //[100 2 3 4 5]
10.删除元素
Go语言中并没有删除切片元素的专用方法,我们可以使用切片本身的特性来删除元素
slice :=[]int{1,2,3,4,5}
slice = append(slice[ :2],slice[3:]...)
fmt.Println(slice) //[1 2 4 5]
要从切片a中删除索引为index的元素,操作方法是a = append(a[:index], a[index+1:]…)