go学习 - append
内置函数(build-in function) append
是向 slice
添加元素,用法:
var x []int x = append(x, 1) x = append(x, 2, 3) x = append(x, 4, 5, 6) x = append(x, x...) // append the slice x fmt.Println(x) // "[1 2 3 4 5 6 1 2 3 4 5 6]"
熟悉 append
内存空间分配策略,有助于编写效率更高的代码。考虑 slice
的结构类型 { pointer, len, cap }
。
slice
指向一段空间,当调用 append
后,cap容量不够,类似于C++的vector的空间分配机制,重新申请一块新的内存空间,容量cap为原来的2倍。
测试代码:
package main import ( "fmt" ) func main() { var res1 = make([]int, 0, 2) res1 = append(res1, 1) var res2 = res1 fmt.Println("***append-1***") res1 = append(res1, 2) res2[0] = 0 fmt.Println("res1:", res1, "&:", &res1[0], "cap:", cap(res1)) fmt.Println("res2:", res2, "&:", &res2[0], "cap:", cap(res2)) fmt.Println("***append-2***") res1 = append(res1, 3) res2[0] = 1 fmt.Println("res1:", res1, "&:", &res1[0], "cap:", cap(res1)) fmt.Println("res2:", res2, "&:", &res2[0], "cap:", cap(res2)) fmt.Println("***append-3***") res1 = append(res1, 4, 5) fmt.Println("res1:", res1, "&:", &res1[0], "cap:", cap(res1)) fmt.Println("***append-4***") res1 = append(res1, 6, 7, 8, 9) fmt.Println("res1:", res1, "&:", &res1[0], "cap:", cap(res1)) // res1 = append(res1, 4, 5, 6, 7, 8, 9) // fmt.Println("res1:", res1, "&:", &res1[0], "cap:", cap(res1)) fmt.Println("***append-5***") arr := [4]int{1, 2, 3, 4} sa := arr[2:] fmt.Println("arr:", arr, "&:", &arr[0], "cap:", cap(arr)) fmt.Println("sa:", sa, "&:", &sa[0], "cap:", cap(sa)) sa = append(sa, 5, 6) fmt.Println("arr:", arr, "&:", &arr[0], "cap:", cap(arr)) fmt.Println("sa:", sa, "&:", &sa[0], "cap:", cap(sa)) } output: ***append-1*** res1: [0 2] &: 0xc0420401c0 cap: 2 -> 修改res2[0]=1,有res1[0]=res2[0]=1 res2: [0] &: 0xc0420401c0 cap: 2 ***append-2*** res1: [0 2 3] &: 0xc0420464c0 cap: 4 -> 重新申请了一块新的内存空间,容量为4 res2: [1] &: 0xc0420401c0 cap: 2 -> 取&res1[0],res1已经指向新的空间;修改res2[0],res1[0]没有变 ***append-3*** res1: [0 2 3 4 5] &: 0xc0420480c0 cap: 8 ***append-4*** res1: [0 2 3 4 5 6 7 8 9] &: 0xc04205a180 cap: 16 ***append-5*** arr: [1 2 3 4] &: 0xc0420465c0 cap: 4 sa: [3 4] &: 0xc0420465d0 cap: 2 arr: [1 2 3 4] &: 0xc0420465c0 cap: 4 sa: [3 4 5 6] &: 0xc042046620 cap: 4 -> sa指向新地址
测试中,出现了一个问题,现在还没找到答案。当 append
函数一次添加多个元素时,分配的内存空间可能出现不是2倍情况,应该是与 append
函数在实现添加多个元素时的策略有关。看代码:
package main import ( "fmt" ) func main() { var res1 = make([]int, 0, 2) res1 = append(res1, 1) fmt.Println("res1:", res1, "&:", &res1[0], "cap:", cap(res1)) -> res1: [1] &: 0xc04200c250 cap: 2 fmt.Println("***append-1***") res1 = append(res1, 2) fmt.Println("res1:", res1, "&:", &res1[0], "cap:", cap(res1)) -> res1: [1 2] &: 0xc04200c250 cap: 2 fmt.Println("***append-2***") res1 = append(res1, 3) fmt.Println("res1:", res1, "&:", &res1[0], "cap:", cap(res1)) -> res1: [1 2 3] &: 0xc042002840 cap: 4 fmt.Println("***append-???***") res1 = append(res1, 4, 5, 6, 7, 8, 9) fmt.Println("res1:", res1, "&:", &res1[0], "cap:", cap(res1)) -> res1: [1 2 3 4 5 6 7 8 9] &: 0xc04200e320 cap: 10 ??? }
goudan-er SHARE · GO
Go