切片追加中的意外行為:如何在不考慮修改的情況下創建多個切片
在 Go在程式碼中操作切片時,你可能會遇到一個令人困惑的問題問題:在循環中將元素追加到切片,然後使用循環結果建立新切片可能會導致最後一個追加覆蓋之前追加的切片。出現此行為的原因是切片引用相同的基礎數組值。
範例:
<code class="go">func create(iterations int) []int { a := make([]int, 0) for i := 0; i < iterations; i++ { a = append(a, i) } return a } func sliceFromLoop() { i := create(11) j := append(i, 100) g := append(i, 101) h := append(i, 102) fmt.Printf("i: %v\nj: %v\ng: %v\nh:%v\n", i, j, g, h) }</code>
在此範例中,sliceFromLoop 函數建立一個切片 i 並附加不同的切片值,產生切片 j、g 和 h。然而,所有三個切片都指向同一個底層數組,因此當最後一個追加修改數組時,它會影響所有切片。
解決方案:複製切片進行獨立修改
基於現有切片創建多個切片並避免修改問題的慣用方法是在附加任何內容之前複製切片。這確保每個新切片都有自己的底層數組。
<code class="go">func makeFromSlice(sl []int) []int { result := make([]int, len(sl)) copy(result, sl) return result }</code>
用法範例:
<code class="go">func main() { i := make([]int, 0) for ii := 0; ii < 11; ii++ { i = append(i, ii) } j := append(makeFromSlice(i), 100) // works fine }</code>
在這個修改後的範例中,我們建立了我在附加 100 之前進行切片。這可以確保 j 引用單獨的底層數組,並且不會受到將來對 i 的修改的影響。
切片文字行為的說明
此問題發生的原因切片文字不會出現這種情況(例如, i := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}),如果追加操作會分配一個新陣列超過後備陣列的容量。此行為與切片文字無關,是附加到切片的基本屬性。
以上是為什麼附加到循環中的切片會影響 Go 中的其他切片?的詳細內容。更多資訊請關注PHP中文網其他相關文章!