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