php小編柚子將為大家解答一個常見的問題:為什麼`append(x, x...)`會將切片複製到Go中的新支援陣列中?在Go程式語言中,`append`函數用於向切片中追加元素。當我們使用`append`函數時,如果切片容量不足,Go會建立一個新的底層數組,並將原有切片中的元素複製到這個新的底層數組中。這是因為在Go中,切片是一個動態數組的引用,當切片容量不夠時,必須建立一個新的陣列來容納更多的元素。這種機制確保了切片的連續性和可擴展性,同時也帶來了一些效能上的損耗。
在go 的切片技巧wiki 和go 庫(例如本範例)中,您有時會看到類似以下的程式碼,用於將切片複製到新的支援數組中。
// In a library at the end of a function perhaps... return append(whateverSlice[:0:0], whateverSlice...) // In an assignment, as in the wiki example... b = append(a[:0:0], a...)
這是我認為我理解的內容:
append
的第二個參數的切片中的所有項目都會複製到新的支援數組中。 append
的第一個參數中,程式碼使用完整切片表達式。 (我們可以將第一個參數重寫為a[0:0:0]
,但如果省略,將提供第一個0
。我認為這與這裡的更大含義無關。)copy
代替 append
,而且讀起來更清晰。)但是,我仍然無法完全理解為什麼語法 append(someslice[:0:0], someslice...)
建立一個新的支援陣列。我最初也很困惑為什麼 append
操作沒有弄亂(或截斷)原始切片。
現在我的猜測:
newslice := oldslice
,那麼對一個的更改將反映在另一個中。通常,您不會想要這樣。 append
的結果分配給原始切片(這在 go 中是正常的),所以原始切片不會發生任何變化。它不會以任何方式被截斷或更改。 anyslice[:0:0]
的長度和容量都為零,因此如果go 要將anyslice
的元素分配給結果,則必須建立一個新的支持數組。這就是建立新後備數組的原因嗎? anyslice...
沒有元素會發生什麼事? go playground 上的片段表明,如果您在空切片上使用此附加技巧,則副本和原始副本最初具有相同的支援數組。 (編輯:正如評論者所解釋的,我誤解了這個片段。該片段顯示這兩個項目最初是相同的,但是都沒有支持數組。它們都指向最初為通用零值。)由於兩個切片的長度和容量都為零,因此當您在其中一個切片中添加任何內容時,該切片將獲得一個新的後備數組。所以我猜,效果還是一樣的。即append
複製後兩個切片不能互相影響。 append
複製方法會立即產生一個新的後備數組。在這種情況下,可以說,生成的兩個切片立即分開。 我可能對此過於擔心,但我希望能更全面地解釋為什麼 append(a[:0:0], a...)
技巧起作用就是這樣。
由於anySlice[:0:0]的長度和容量都為零,因此如果Go要將anySlice的元素分配給結果,則必須建立一個新的後備數組。這就是建立新支援數組的原因嗎?
因為容量是0
,是的。
https://pkg.go.dev/[電子郵件受保護]#append
如果有足夠的容量,則會對目標進行重新切片以容納新元素。如果沒有,將會分配一個新的底層數組。
cap=0
對於非空切片來說是不夠的,需要分配一個新陣列。 以上是為什麼 `append(x, x...)` 將切片複製到 Go 中的新支援數組中?的詳細內容。更多資訊請關注PHP中文網其他相關文章!