Home > Backend Development > Golang > Why Does Appending Pointers in Go's `append` Function Lead to Unexpected Overwriting?

Why Does Appending Pointers in Go's `append` Function Lead to Unexpected Overwriting?

Barbara Streisand
Release: 2024-12-25 03:36:17
Original
750 people have browsed it

Why Does Appending Pointers in Go's `append` Function Lead to Unexpected Overwriting?

Unexpected Overwriting Issue with Go's "append" Function

In Go, the append function is frequently used to extend slices with additional elements. However, occasionally, unexpected behavior can occur when appending pointers to structures.

Consider the following code snippet:

import "fmt"

type Foo struct {
    val int
}

func main() {
    var a = make([]*Foo, 1)
    a[0] = &Foo{0}

    var b = [3]Foo{Foo{1}, Foo{2}, Foo{3}}
    for _, e := range b {
        a = append(a, &e)
    }

    for _, e := range a {
        fmt.Printf("%v ", *e)
    }
}
Copy after login

Intriguingly, instead of printing {0} {1} {2} {3}, the code outputs {0} {3} {3} {3}. This unexpected behavior stems from a fundamental aspect of Go's behavior:

Copies in for Range Loops

Go iterates over slices and arrays using for range loops, which create a copy of each element during iteration. In our code, the for range loop variable e represents a temporary copy of the array element b[i]. Unfortunately, we are then appending the address of this temporary variable to the slice a.

The Fix

To resolve this issue, we need to append the address of the original array element instead of the temporary copy. By modifying the for loop to use the index i, we ensure that the correct address is appended to the slice:

for i := range b {
    a = append(a, &b[i])
}
Copy after login

This change yields the expected output of {0} {1} {2} {3}.

Reason for the Behavior

Go's lack of true references contributes to this behavior. In C or Java, where references are used, the loop variable would directly reference the array element, allowing mutations via the loop variable. However, in Go, the loop variable is a distinct variable that holds a copy of the element, not a reference. Consequently, changes made to the loop variable are not reflected in the original array elements.

The above is the detailed content of Why Does Appending Pointers in Go's `append` Function Lead to Unexpected Overwriting?. 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