Go 的 slice 可以看成一個帶有一些資訊及指向底層 array 指標的 struct。append() 會依照底層 array 擁有的空間以及空間擴張演算法決定是否 allocate 一塊新的 array 來當底層 array。
以下用兩個例子顯示有時候 append() 會 allocate 新的底層 array,有時不會。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func main() { x := make([]int, 5)
fmt.Println("x =", x) fmt.Println("---")
y := append(x, 3) fmt.Println("x =", x) fmt.Println("y =", y) fmt.Println("---")
x[0] = 123 fmt.Println("x =", x) fmt.Println("y =", y) }
|
執行結果:
1 2 3 4 5 6 7
| x = [0 0 0 0 0] --- x = [0 0 0 0 0] y = [0 0 0 0 0 3] --- x = [123 0 0 0 0] y = [0 0 0 0 0 3]
|
這個例子可以看到 append 後的 y 底層的 array 已經跟 x 底層的 array 不同。
再來看看底層 array 相同的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| func main() { x := make([]int, 5) x = x[:3] fmt.Println("x =", x) fmt.Println("---")
y := append(x, 3) fmt.Println("x =", x) fmt.Println("y =", y) fmt.Println("---")
x[0] = 123 fmt.Println("x =", x) fmt.Println("y =", y) }
|
執行結果:
1 2 3 4 5 6 7
| x = [0 0 0] --- x = [0 0 0] y = [0 0 0 3] --- x = [123 0 0] y = [123 0 0 3]
|
從結果可以看到,當把 x[0] 設為 123 時 y[0] 也變成 123,表示 x 與 y 的底層 array 是相同的。
我們不知道 append() 操作後,是否會重新分配 array。因此不能假設 append() 操作後產生的 slice 跟原本的 slice 是同一個,通常會寫成: