以前有研究過 Go silce 的指針,後來看了一些文章,才知道說 Go 本身在底層還有一個 array 來處理 slice。
簡單說,我今天建立一個 slice,實際上同時建立了一個 array
而array 實際上就是個指針
所以執行以下 code 會 print 出同樣的值
arr1 := []int{1, 2, 3}
arr2 := arr1
fmt.Printf("%p\n", &arr1[2])
fmt.Printf("%p\n", &arr2[2])
換言之,arr1[1] = 10
同時會更改到 arr2[1]
,因為兩者底層的 array 是同一個。
這裡提一個有趣的狀況,同樣 arr2 := arr1
,但 arr1 有藉由調整過大小:
arr1 := []int{1, 2, 3, 4, 5, 6, 7}
arr2 := arr1
arr1 = append(arr1[0:1], arr1[2:]...)
fmt.Printf("%p\n", &arr1[2])
fmt.Printf("%p\n", &arr2[2])
append(slice []Type, elems ...Type) []Type
會直接更動 slice 底下的 array,而 arr2 和 arr1 對應的 array 又相同,所以兩邊的值都會變更。
但,這段code,如果 print append完後的兩個 array,會發現:
arr1 [1 3 4 5 6 7] arr2 [1 3 4 5 6 7 7]
再來看這段 code:
arr1 := []int{1, 2, 3, 4, 5, 6, 7}
arr2 := append(arr1[0:2], 10)
fmt.Println("arr1", arr1)
fmt.Println("arr2", arr2)
輸出結果是
arr1 [1 2 10 4 5 6 7] arr2 [1 2 10]
從上面兩段 code 可以知道,append(slice []Type, elems ...Type) []Type
的動作是
- 先去看
slice []Type
對應的 array 以及slice []Type
的長度 - 在該長度後面添值
所以對於 append(arr1[0:2], 10)
這段,即是
- 找到 slice arr1 對應的 array
- 因為 array 的長度超過 3,所以直接更改 array[3]
- 將
[ array[0], array[1], array[2], array[3] ]
轉成 slice 存到變數 arr2
參考資料
骏马金龙, (2018, October 26). Go基础系列:Go slice详解. 博客园. https://www.cnblogs.com/f-ck-need-u/p/9854932.html
沒有留言:
張貼留言