总结:
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:
var a = []int{1, 3, 4, 5}slice a : [1 3 4 5] , len(a) : 4b := a[1:2]slice b : [3] , len(b) : 1c := b[0:3]slice c : [3 4 5] , len(c) : 3
一.切片的创建 :
1.数组中获取
vararr[3]int0-2fmt.Println(arr[0:2])2-~fmt.Println(arr[2:])0-2fmt.Println(arr[:2])0-~fmt.Println(arr[:])
2.新建
//未分配内存var b[]int//已分配内存var c=[]int{}fmt.Println(b==nil)fmt.Println(c==nil)
3.使用make
//使用make创建一个新的切片,类型,元素的个数,预分配存储空间,后面要大于前面的提高性能a:=make([]int,1,5)
二.切片的操作
追加一个元素
a=append(a,1)fmt.Println(a)
添加多个
a=append(a,1,2,3)fmt.Println(a)
添加一个切片,需要在末尾加上(…)展开符
a=append(a,[]int{1,2,3}...)fmt.Println(a)a=append(a,arr[:]...)fmt.Println(a)
在切片开头加上元素
a=append([]int{0},a...)
在任意位置插入数据
a=append(a[:2],(append([]int{7,8,9},a[2:]...))...)
三.切片的优化(重要)
内存优化
切片持有对底层数组的引用。只要切片在内存中,数组就不能被垃圾回收。在内存管理方面,这是需要注意的。让我们假设我们有一个非常大的数组,我们只想处理它的一小部分。然后,我们由这个数组创建一个切片,并开始处理切片。这里需要重点注意的是,在切片引用时数组仍然存在内存中。
一种解决方法是使用 copy 函数 func copy(dst,src[]T)int 来生成一个切片的副本。这样我们可以使用新的切片,原始数组可以被垃圾回收。
package mainimport ("fmt")func countries() []string {countries := []string{"USA", "Singapore", "Germany", "India", "Australia"}neededCountries := countries[:len(countries)-2]countriesCpy := make([]string, len(neededCountries))copy(countriesCpy, neededCountries) //copies neededCountries to countriesCpy return countriesCpy }func main() { countriesNeeded := countries() fmt.Println(countriesNeeded) }
在线运行程序
在上述程序的第 9 行,neededCountries := countries[:len(countries)-2 创建一个去掉尾部 2 个元素的切片 countries,在上述程序的 11 行,将 neededCountries 复制到 countriesCpy 同时在函数的下一行返回 countriesCpy。现在 countries 数组可以被垃圾回收, 因为 neededCountries 不再被引用。
