go-切片的追加
阿新 • • 發佈:2022-03-26
// The append built-in function appends elements to the end of a slice. If // it has sufficient capacity, the destination is resliced to accommodate the // new elements. If it does not, a new underlying array will be allocated. // Append returns the updated slice. It is therefore necessary to store the // result of append, often in the variable holding the slice itself: // slice = append(slice, elem1, elem2) // slice = append(slice, anotherSlice...) // As a special case, it is legal to append a string to a byte slice, like this: // slice = append([]byte("hello "), "world"...) func append(slice []Type, elems ...Type) []Type
- 該函式的作用是追加元素到切片slice的末尾。
- 如果slice還有剩餘的容量,則該切片被允許容納新的元素;如果沒有剩餘容量,一個新的底層陣列將會建立。
- 該函式返回更新的切片,因此新的切片必須儲存追加結果,通常更新的切片也包含原切片本身。
package test import ( "fmt" "testing" ) func TestSize(t *testing.T) { a := []int{1, 2, 3, 4, 5, 6} fmt.Printf("aaaa 的地址: %p ,長度 :%d %#v\n", a, len(a), a) for i := 0; i < len(a); i++ { fmt.Printf("a[%d] 的地址: %p \n", i, &a[i]) } // b 引用a索引為 2的元素 b := a[2:3] fmt.Printf("bbbb 的地址: %p ,長度 :%d %#v\n", b, len(b), b) for i := 0; i < 16; i++ { b = append(b, 30) fmt.Printf("b----b 的地址: %p ,長度 :%d %#v\n", b, len(b), b) //fmt.Printf("a----a 的地址: %p ,長度 :%d %#v\n", a, len(a), a) } }
=== RUN TestSize aaaa 的地址: 0xc000020420 ,長度 :6 []int{1, 2, 3, 4, 5, 6} a[0] 的地址: 0xc000020420 a[1] 的地址: 0xc000020428 a[2] 的地址: 0xc000020430 // b 的引用地址 a[3] 的地址: 0xc000020438 a[4] 的地址: 0xc000020440 a[5] 的地址: 0xc000020448 b 的地址: 0xc000020430 ,容量: 4,長度 :1 []int{3} b 的地址: 0xc000020430 ,容量: 4,長度 :2 []int{3, 30} b 的地址: 0xc000020430 ,容量: 4,長度 :3 []int{3, 30, 30} b 的地址: 0xc000020430 ,容量: 4,長度 :4 []int{3, 30, 30, 30} //擴容後,地址改變 b 的地址: 0xc00001a280 ,容量: 8,長度 :5 []int{3, 30, 30, 30, 30} b 的地址: 0xc00001a280 ,容量: 8,長度 :6 []int{3, 30, 30, 30, 30, 30} b 的地址: 0xc00001a280 ,容量: 8,長度 :7 []int{3, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00001a280 ,容量: 8,長度 :8 []int{3, 30, 30, 30, 30, 30, 30, 30} //擴容後,地址改變 b 的地址: 0xc000116180 ,容量: 16,長度 :9 []int{3, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc000116180 ,容量: 16,長度 :10 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc000116180 ,容量: 16,長度 :11 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc000116180 ,容量: 16,長度 :12 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc000116180 ,容量: 16,長度 :13 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc000116180 ,容量: 16,長度 :14 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc000116180 ,容量: 16,長度 :15 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc000116180 ,容量: 16,長度 :16 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} //擴容後,地址改變 b 的地址: 0xc00000a700 ,容量: 32,長度 :17 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :18 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :19 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :20 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :21 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :22 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :23 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :24 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :25 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :26 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :27 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :28 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :29 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :30 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :31 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00000a700 ,容量: 32,長度 :32 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} //擴容後,地址改變 b 的地址: 0xc00014e000 ,容量: 64,長度 :33 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00014e000 ,容量: 64,長度 :34 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00014e000 ,容量: 64,長度 :35 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00014e000 ,容量: 64,長度 :36 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00014e000 ,容量: 64,長度 :37 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00014e000 ,容量: 64,長度 :38 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00014e000 ,容量: 64,長度 :39 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00014e000 ,容量: 64,長度 :40 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} b 的地址: 0xc00014e000 ,容量: 64,長度 :41 []int{3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30} --- PASS: TestSize (0.00s) PASS Process finished with the exit code 0
從上面程式的輸出可以看出
- 向 b 中追加資料會覆蓋 a 中的資料。
- 當切片b的長度超過陣列a固有長度時,b 的地址改變了。
- 當切片容量被用完時,如果繼續追加,則切片擴容後的大小為切片當前大小2 倍。