Home > Article > Backend Development > Why Does Appending to a Slice in a Loop Affect Other Slices in Go?
Unexpected Behavior in Slice Append: How to Create Multiple Slices Without Modification Concerns
When manipulating slices in Go code, you may encounter a puzzling issue: appending elements to a slice within a loop and then using the loop result to create new slices can result in the last append overriding the slices from previous appends. This behavior arises because the slices reference the same underlying array values.
Example:
<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>
In this example, the sliceFromLoop function creates a slice i and appends different values to it, resulting in the slices j, g, and h. However, all three slices point to the same underlying array, so when the last append modifies the array, it affects all slices.
Solution: Copying Slices for Independent Modifications
The idiomatic way to create multiple slices based on an existing slice and avoid modification concerns is by copying the slice before appending anything. This ensures that each new slice has its own underlying array.
<code class="go">func makeFromSlice(sl []int) []int { result := make([]int, len(sl)) copy(result, sl) return result }</code>
Example Usage:
<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>
In this revised example, we create a copy of the i slice before appending 100 to it. This ensures that j references a separate underlying array and won't be affected by future modifications to i.
Explanation of Slice Literal Behavior
The reason why this issue does not arise with slice literals (e.g., i := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) is that a new array is allocated if the append operation would exceed the capacity of the backing array. This behavior is unrelated to slice literals and is a fundamental property of appending to slices.
The above is the detailed content of Why Does Appending to a Slice in a Loop Affect Other Slices in Go?. For more information, please follow other related articles on the PHP Chinese website!