意外的切片追加行為
問題介紹
將元素追加到切片內的元素追加到切片內的元素追加到切片內的元素追加到切片內的元素追加到切片內的元素追加到切片時循環,隨後嘗試從循環結果建立新切片會出現意外行為。具體來說,最後一個追加元素會涵蓋先前追加的結果。當基於循環迭代獲得的切片建立新切片時,會出現此問題。
分析
觀察到的行為源自於 Go 切片和陣列都使用的事實相同的底層資料結構。當附加到切片時,Go 會建立一個引用相同底層陣列的新切片物件。這意味著對原始切片所做的任何更改也會影響新切片。
解
為了避免這種行為,必須在製作之前複製切片任何修改。這將創建一個新的切片對象,該對象具有對底層數組的獨立引用。實現此目的的慣用方法是使用複製函數:
<code class="go">func makeFromSlice(sl []int) []int { result := make([]int, len(sl)) copy(result, sl) return result }</code>
透過將 makeFromSlice(i) 的結果分配給主函數中的 j,我們創建了一個獨立於原始 i 的新切片片。這個新切片可以安全地修改,而不影響原始切片。
與切片文字比較
切片文字,例如{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},當追加的陣列超出其容量時,總是會分配一個新的底層陣列。這解釋了為什麼 sliceFromLiteral 的行為符合預期。
結論
使用切片時,請務必記住在修改它們之前先進行複製。這確保了對新切片所做的更改不會影響原始切片。複製功能提供了一種慣用且有效的方法來執行此操作。
以上是為什麼從循環建立新切片時切片追加行為會改變?的詳細內容。更多資訊請關注PHP中文網其他相關文章!