内建函数append()
作用:
内建函数 append() 可以为切片动态添加元素
尾部添加元素
头部添加元素
切片扩容
使用
append()
拼接切片
尾部添加元素
代码实现:
package main
import "fmt"
func main() {
/*声明一个切片*/
var array []int
/*追加一个元素*/
array = append(array, 1)
/*追加多个元素*/
array = append(array, 1,2,3)
/*追加一个切片*/
array = append(array, []int{1,2,3,4,5}...)
/*
追加一个切片需要对追加的切片进行压缩。书写格式为:[]int{}...
后面三个"..."符号必不可少,是压缩的标识符
[]int{1,2,3,4,5}...这个不是一个新建的数组切片对象放入array当中,而是将元素放入slice当中
*/
fmt.Println(array)
}
头部添加元素
代码实现:
package main
import "fmt"
func main() {
/*新建切片*/
var array = []int{2,3,4}
/*开头添加传参需要改变,并且需要对原数组进行压缩*/
array = append([]int{0,1}, array...)
/*
这个操作再内存层面已经对原来的切片进行了复制扩容
1、先复制原有的切片
2、再创建一个更大的切片空间
3、将添加的元素和原有的切片元素赋值进入到创建的切片空间
*/
fmt.Println(array)
}
在切片开头添加元素会导致内存的重新分配,而且会导致已有元素全部被复制 1 次,从切片的开头添加元素的性能要比从尾部追加元素的性能差很多。
切片扩容
扩容规律:
按容量的 2 倍数进行扩充
package main
import "fmt"
func main() {
/*声明一个切片*/
var array []int
/*循环往里面赋值*/
for i := 0; i < 10; i++ {
/*使用append函数往切片里面添加元素*/
array = append(array, i)
fmt.Printf("len:%d,cap:%d,pointer:%p
", len(array), cap(array), array)
/*
1、len函数查看切片拥有的元素个数
2、cap函数查看切片容量情况
*/
}
}
通过len()
函数和cap()
函数很好的反映出了容量的变化情况:
-
容量达到上限时都按照2的倍数进行扩容
-
切片长度 len 并不等于切片的容量 cap。
使用append()
函数拼接切片
append()
函数返回的是一个新切片,所以支持链式操作
package main
import "fmt"
func main() {
/*声明一个切片*/
var array = []int{2,3,4,5,6}
/*通过添加append的切片实现切片的拼接*/
array = append(array[:3], append([]int{0,1}, array[1:]...)...)
fmt.Println(array)
}
-
每个添加操作中的第二个 append 调用都会创建一个临时切片,并将append[i:] 的内容复制到新创建的切片中
-
再将临时创建的切片再追加到 append[:i] 中。
代码分析:
-
先执行里面的
append([]int{0,1}, array[1:]...)...
再切片的array[1:]
开头添加切片[]int{0,1}
返回一个临时切片[0,1,3,4,5,6]
-
再执行外层的
append()
在原切片的前3号索引[2,3,4]
然后再将返回的零食切片拼接到原切片前三好索引后
这里对切片进行了扩容:
package main
import "fmt"
func main() {
/*声明一个切片*/
var array = []int{2,3,4,5,6}
/*通过添加append的切片实现切片的拼接*/
array = append(array[:3], append([]int{0,1}, array[1:]...)...)
/*
左闭右开:
1、左边闭合的区间,左边的索引的值会取到该索引所在的位置
2、右边开放的区间,右边索引的值会取到该索引前一位的位置
*/
fmt.Println(array)
fmt.Println(array[:3])
fmt.Printf("len:%d,cap:%d,pointer:%p", len(array), cap(array), array)
}