2.3 切片(slice)

切片(slice)是对数组一个连续片段的引用。它是指向底层数组的指针。不需要定义长度。和数组在写法上的区别就是不需要指定长度。

声明:

  1. var identifier []type (不需要说明长度)

示例

  1. var s []string
  2. s:=[]string{}

添加内容到切片

  1. s = append(s, "fsd")

取截取数组到切片

  1. s := []string{"dd", "fsdf"}
  2. slice1 := s[1:2] //[开始:结束] 开始和结束不能大于数组实际长度
  3. fmt.Println(slice1)

注意切片不能再重新切片,如

  1. slice1 := slice1[:1] 这样会报错:no new variables on left side of :=

但可以对切片添加内容

  1. slice1 = append(slice1, "aa", "bb")

合并两个切片

  1. s1 := []int{1, 2}
  2. s2 := []int{1, 4}
  3. s1 = append(s1, s2...)
  4. fmt.Println(s1)

输出:[1 2 1 4]

注意: append切片时候要记着家”…”,这是因为append()一个可变参数函数,…允许您从切片将多个参数传递给可变参数函数。

插入指定位置

  1. s := []string{"aa", "bb", "cc", "dd"}
  2. //插入指定位置
  3. index := 2
  4. temp := append([]string{}, s[index:]...)
  5. s = append(s[:index], "ee")
  6. s = append(s, temp...)
  7. fmt.Println(s) //[aa bb ee cc dd]

删除指定索引元素

  1. s := []string{"aa", "bb","ee", "cc", "dd"}
  2. //删除指定索引元素
  3. index = 2
  4. s = append(s[:index], s[index+1:]...)
  5. fmt.Println(s) //[aa bb cc dd]

删除指定值元素

  1. s := []string{"aa", "bb", "cc", "dd"}
  2. value := "dd"
  3. //删除指定值
  4. for k, v := range s {
  5. if v == value {
  6. s = append(s[:k], s[k+1:]...)
  7. }
  8. }
  9. fmt.Println(s) //[aa bb cc]

make() 创建一个切片

当相关数组还没有定义时,我们可以使用 make() 函数来创建一个切片 同时创建好相关数组:

var slice1 []type = make([]type, len)

也可以简写为 slice1 := make([]type, len),这里 len 是数组的长度并且也是 slice 的初始长度。

示例:

var slice1 []string = make([]string , 10)

new() 和 make() 的区别

看起来二者没有什么区别,都在堆上分配内存,但是它们的行为不同,适用于不同的类型。

  • new(T) 为每个新的类型T分配一片内存,初始化为 0 并且返回类型为T的内存地址:这种方法 *返回一个指向类型为 T,值为 0 的地址的指针,它适用于值类型如数组和结构体;它相当于 &T{}
  • make(T) 返回一个类型为 T 的初始值,它只适用于3种内建的引用类型:切片、map 和 channel。

换言之,new 函数分配内存,make 函数初始化;

  1. p := new([2]int) //p指针,也可以使用[]进行赋值
  2. p[0] = 22
  3. b := make([]int, 10, 50) //第一个参数是类型,第二个参数是分配的空间,第三个参数是预留分配空间
  4. b[0] = 13
  5. fmt.Println(p, b)
  6. 打印结果:
  7. &[22 0] [13 0 0 0 0 0 0 0 0 0]

如果想用预留空间

  1. package main
  2. import "fmt"
  3. func main() {
  4. p := new([2]int)
  5. p[0] = 22
  6. b := make([]int, 10, 50) //第一个参数是类型,第二个参数是分配的空间,第三个参数是预留分配空间
  7. a := b[:cap(b)]
  8. fmt.Println(a)
  9. }

结果:

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

多维切片(slice)**

也是同数组一样,slice 可以组合为多维的 slice:

  1. slice := [][]int{{10}, {20, 30}}
  2. slice[0] = append(slice[0], 20)

links