切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。
切片的本质就是对底层数组的封装,包含了三个信息:底层数组的指针、切片的长度和切片的容量

1.切片的定义

  1. var a []string
  2. var b =[]int{}
  3. var c=[]bool{false,true}
  4. fmt.Println(a,b,c) //[] [] [false true]
  5. fmt.Println(a==nil) //true
  6. fmt.Println(b==nil) //flase

2.切片的长度和容量

使用内置的len()函数求长度,使用内置的cap()函数求切片的容量

  1. var array=[]bool{false,true}
  2. fmt.Println(len(array))
  3. fmt.Println(cap(array))

3.切片表达式

3.1简单切片表达式

  1. a := [5]int{1,2,3,4,5}
  2. s := a[0:3] //基于数组通过切片表达式得到切片
  3. fmt.Println(cap(s))
  4. fmt.Println(len(s))
  1. a := [5]int{1,2,3,4,5}
  2. s := a[3:4] //基于数组通过切片表达式得到切片
  3. fmt.Println(cap(s)) //2
  4. fmt.Println(len(s)) //1

3.2完整切片表达式

  1. //a[low : high : max]
  2. a := [5]int{1,2,3,4,5}
  3. t := a[1:3:4]
  4. fmt.Println(t) //2 3
  5. fmt.Println(len(t)) //2
  6. fmt.Println(cap(t)) //3

完整切片表达式需要满足的条件是0 <= low <= high <= max <= cap(a)

4.使用make()函数构造切片

基于数组来创建的切片,如果需要动态的创建一个切片,我们就需要使用内置的make()函数

  1. make([]T, size, cap)
  2. T:切片的元素类型
  3. size:切片中元素的数量
  4. cap:切片的容量
  1. a := make([]int,2,10)
  2. fmt.Println(a)
  3. fmt.Println(len(a))
  4. fmt.Println(cap(a))

5.判断切片是否为空

要检查切片是否为空,请始终使用len(s) == 0来判断,而不应该使用s == nil来判断。

  1. var a1 []int
  2. a2 := []int{}
  3. a3 := make([]int,0)
  4. fmt.Println(len(a1),cap(a1)) //0 0
  5. fmt.Println(len(a2),cap(a2)) //0 0
  6. fmt.Println(len(a3),cap(a3)) //0 0
  7. fmt.Println(a1==nil) //true
  8. fmt.Println(a2==nil) //false
  9. fmt.Println(a3==nil) //false
  1. array := make([]int,0)
  2. fmt.Println(len(array)==0) //切片为空

6.切片的赋值拷贝

  1. array := make([]int,3)
  2. a := array //赋值后共用一个底层数组
  3. a[0] =100
  4. fmt.Println(array) //[100 0 0]
  5. fmt.Println(a) //[100 0 0]

7.切片遍历

  1. slice := []int{1,3,5}
  2. for index,value := range slice {
  3. fmt.Println(index,value)
  4. }
  5. fmt.Println("-------------------")
  6. for i := range slice{
  7. fmt.Println(i,slice[i])
  8. }

8.添加元素

  1. var slice []int
  2. slice = append(slice,1)
  3. slice = append(slice,2,3,4,5)
  4. fmt.Println(slice)
  1. slice := []int{1,2,3}
  2. slice = append(slice,4,5,6)
  3. fmt.Println(slice)

append()函数将元素追加到切片的最后并返回该切片。
切片的容量按照1,2,4,8,16这样的规则自动进行扩容,每次扩容后都是扩容前的2倍
append()函数还支持一次性追加多个元素

  1. var slice []int
  2. for i := 0; i < 10; i++ {
  3. slice = append(slice,i)
  4. fmt.Println(slice, len(slice), cap(slice))
  5. }
  6. 输出结果:
  7. [0] 1 1
  8. [0 1] 2 2
  9. [0 1 2] 3 4
  10. [0 1 2 3] 4 4
  11. [0 1 2 3 4] 5 8
  12. [0 1 2 3 4 5] 6 8
  13. [0 1 2 3 4 5 6] 7 8
  14. [0 1 2 3 4 5 6 7] 8 8
  15. [0 1 2 3 4 5 6 7 8] 9 16
  16. [0 1 2 3 4 5 6 7 8 9] 10 16

9.复制切片

由于切片是引用类型,slice1和slice2其实都指向了同一块内存地址。修改slice2的同时slice1的值也会发生变化。

  1. slice1 :=[]int{1,2,3,4,5}
  2. slice2 := slice1
  3. fmt.Println(slice1)
  4. fmt.Println(slice2)
  5. slice2[0] = 0
  6. fmt.Println(slice1)
  7. fmt.Println(slice2)

copy()函数可以迅速地将一个切片的数据复制到另外一个切片空间

  1. slice1 :=[]int{1,2,3,4,5}
  2. slice2 := make([]int,5,10)
  3. copy(slice2,slice1)
  4. fmt.Println(slice2) //[1 2 3 4 5]
  5. slice2[0]=100
  6. fmt.Println(slice1) //[1 2 3 4 5]
  7. fmt.Println(slice2) //[100 2 3 4 5]

10.删除元素

Go语言中并没有删除切片元素的专用方法,我们可以使用切片本身的特性来删除元素

  1. slice :=[]int{1,2,3,4,5}
  2. slice = append(slice[ :2],slice[3:]...)
  3. fmt.Println(slice) //[1 2 4 5]

要从切片a中删除索引为index的元素,操作方法是a = append(a[:index], a[index+1:]…)