Chao Sun
Chao Sun

Reputation: 685

Golang array update doesn't work

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

Answers (2)

captncraig
captncraig

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)

playground link

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

Dan 0
Dan 0

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

Related Questions