Reputation: 685
Hi Golang newbie coming from Java world. I have this very simple piece of program:
package main
import "fmt"
type Foo struct {
A [5]int
}
func main() {
s := make([]Foo, 0)
var foo Foo
s = append(s, foo)
foo.A[0] = 42
fmt.Printf("%v", s[0].A)
}
However, this prints [0,0,0,0,0]
instead of [42,0,0,0,0]
that I expected. After swapping the line s = append(s, foo)
and foo.A[0] = 42
, it does print [42,0,0,0,0]
. Why is that? Thanks in advance.
Upvotes: 1
Views: 1951
Reputation: 23068
s
is a slice with elements of type Foo
. Foo
is a struct type. Structs, when assigned to a value, passed as an argument, or appended to a slice, are copied by value. Your append
line is adding a copy of foo
to s
, while you intended to add a reference to foo
.
To fix, make s
a slice of pointers to your struct:
s := make([]*Foo)
var foo Foo
s = append(s, &foo)
Pointers may seem scary to people who have only experienced them painfully in c. In go, they simply allow you to control if you want to copy something or pass a reference to it.
Upvotes: 3
Reputation: 924
In your example you are appending foo
as it currently exists to s
. This copies foo
by value, creating a copy of foo
appended to s
. When you print s
, you're printing the newly created (when it was initialized to 0) foo
that was added to s
, not the modified foo
array.
When you switch s = append(s, foo)
and foo.A[0] = 42
, you're doing the same thing, but this time you're seeing your expected result because you're copying the foo
array, with 42, into s
. If you were to modify foo
again fmt.Printf("%v", s[0].A)
would still give you [42,0,0,0,0]
Upvotes: 2