Why Does Appending to a Slice in a Loop Affect Other Slices in Go?

Barbara Streisand
Release: 2024-11-06 04:05:02
Original
978 people have browsed it

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>
Copy after login

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>
Copy after login

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>
Copy after login

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!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!