copy 是唯一真的複製 slice 資料的方式
用
:切、傳進 function、指派給另一個變數——這些都只複製 header。真的把資料搬到新記憶體的只有copy。
func copy(dst, src []T) int // 回傳實際複製了幾個元素複製幾個以 dst 的 length 為準:
scores := []int{1, 2, 3, 4, 5}
cloneScores := make([]int, 4)
copy(cloneScores, scores[:3]) // [1 2 3 0] ← 不足的補 zero value- dst 比 src 長 → 多出來的位置留 zero value
- dst 比 src 短 → 超過的元素不會被複製進去(不會 panic,也不會自動長大)
手動擴容的三個步驟
append 在 cap 不夠時做的事,用 copy 寫出來就是這三步:
t := make([]byte, len(s), (cap(s)+1)*2) // 1. 開一塊更大的新 array(+1 是為了 cap(s) 為 0)
copy(t, s) // 2. 把舊資料搬進去
s = t // 3. 讓 s 改指向新的窗戶第 3 步不能省。因為 array 的大小是型別的一部分、開好就不能改,所謂「擴充 capacity」永遠是「開一塊新的 → 搬過去 → 改指向」;少了 s = t,s 還指著舊的小 array,前兩步等於白做。做完之後舊 array 沒人引用,交給 GC。
相關:append 的行為取決於 cap 夠不夠、切割出的 slice 預設 cap 吃到底,append 會寫進鄰居的地盤