总结:

slice 并不是数组或数组指针。它通过内部指针和相关属性引用数组片段,以实现变长方案。

- 切片:切片是数组的一个引用,因此切片是引用类型。但自身是结构体,值拷贝传递。
- 切片遍历方式和数组一样,可以用len()求长度。表示可用元素数量,读写操作不能超过该限制。
- cap可以求出slice最大扩张容量,不能超出数组限制。0 <= len(slice) <= len(array),其中array是slice引用的数组。
- 切片的定义:var 变量名 []类型,比如 var str []string var arr []int。
- 如果 slice == nil,那么 len、cap 结果都等于 0。
- 如果切片中元素超出cap,那么就会重新分配底层数组,与原数组无关,一般会2倍的容量重新分配数组,建议一次性分配足够大的空间,及时释放不使用的slice,避免gc无法回收
- 及时将所需数据copy到较小的slice中,以便释放超大号的底层数组内存
- 在切片的基础上再切片,实际上还是操作底层数组,但是下标为0的元素,根据上一个切片决定如实例1:
- slice[:6:8]的意思是从0到6,最大容量为8
- 将切片或者数组转换成字符串strings.Replace(strings.Trim(fmt.Sprint(array_or_slice), “[]”), “ “, “,”, -1)

实例1:

  1. var a = []int{1, 3, 4, 5}
  2. slice a : [1 3 4 5] , len(a) : 4
  3. b := a[1:2]
  4. slice b : [3] , len(b) : 1
  5. c := b[0:3]
  6. slice c : [3 4 5] , len(c) : 3

一.切片的创建 :

1.数组中获取

  1. vararr[3]int
  2. 0-2
  3. fmt.Println(arr[0:2])
  4. 2-~
  5. fmt.Println(arr[2:])
  6. 0-2
  7. fmt.Println(arr[:2])
  8. 0-~
  9. fmt.Println(arr[:])

2.新建

  1. //未分配内存
  2. var b[]int
  3. //已分配内存
  4. var c=[]int{}
  5. fmt.Println(b==nil)
  6. fmt.Println(c==nil)

3.使用make

  1. //使用make创建一个新的切片,类型,元素的个数,预分配存储空间,后面要大于前面的提高性能
  2. a:=make([]int,1,5)

二.切片的操作

追加一个元素

  1. a=append(a,1)
  2. fmt.Println(a)

添加多个

  1. a=append(a,1,2,3)
  2. fmt.Println(a)

添加一个切片,需要在末尾加上(…)展开符

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

在切片开头加上元素

  1. a=append([]int{0},a...)

在任意位置插入数据

  1. a=append(a[:2],(append([]int{7,8,9},a[2:]...))...)

三.切片的优化(重要)

内存优化
切片持有对底层数组的引用。只要切片在内存中,数组就不能被垃圾回收。在内存管理方面,这是需要注意的。让我们假设我们有一个非常大的数组,我们只想处理它的一小部分。然后,我们由这个数组创建一个切片,并开始处理切片。这里需要重点注意的是,在切片引用时数组仍然存在内存中。
一种解决方法是使用 copy 函数 func copy(dst,src[]T)int 来生成一个切片的副本。这样我们可以使用新的切片,原始数组可以被垃圾回收。

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func countries() []string {
  6. countries := []string{"USA", "Singapore", "Germany", "India", "Australia"}
  7. neededCountries := countries[:len(countries)-2]
  8. countriesCpy := make([]string, len(neededCountries))
  9. copy(countriesCpy, neededCountries) //copies neededCountries to countriesCpy return countriesCpy }
  10. func main() { countriesNeeded := countries() fmt.Println(countriesNeeded) }

在线运行程序
在上述程序的第 9 行,neededCountries := countries[:len(countries)-2 创建一个去掉尾部 2 个元素的切片 countries,在上述程序的 11 行,将 neededCountries 复制到 countriesCpy 同时在函数的下一行返回 countriesCpy。现在 countries 数组可以被垃圾回收, 因为 neededCountries 不再被引用。