Golang数组更新不起作用。

huangapple go评论83阅读模式
英文:

Golang array update doesn't work

问题

你好,Golang新手,来自Java世界。我有一个非常简单的程序:

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)
}

然而,这段代码打印的结果是[0,0,0,0,0],而不是我期望的[42,0,0,0,0]。当我交换了s = append(s, foo)foo.A[0] = 42这两行的顺序后,它确实打印出了[42,0,0,0,0]。为什么会这样呢?提前谢谢你的帮助。

英文:

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.

答案1

得分: 2

s是一个包含类型为Foo的元素的切片。Foo是一个结构体类型。当结构体被赋值给一个变量、作为参数传递或附加到切片时,它们是按值复制的。你的append行将一个foo副本添加到s中,而你本意是要添加一个对foo引用

要修复这个问题,将s定义为指向你的结构体的指针的切片:

s := make([]*Foo, 0)
var foo Foo
s = append(s, &foo)

playground链接

对于那些只在C语言中痛苦地经历过指针的人来说,指针可能看起来很可怕。在Go语言中,指针只是允许你控制是否要复制某个东西或者传递对它的引用。

英文:

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.

答案2

得分: 2

在你的示例中,你将 foo 作为它当前的形式附加到 s 上。这会通过值复制 foo,创建一个附加到 sfoo 的副本。当你打印 s 时,你打印的是新创建的(当它被初始化为0时)附加到 sfoo,而不是修改后的 foo 数组。

当你交换 s = append(s, foo)foo.A[0] = 42 时,你做的是同样的事情,但这次你看到了你期望的结果,因为你将带有42的 foo 数组复制到了 s 中。如果你再次修改 foofmt.Printf("%v", s[0].A) 仍然会给出 [42,0,0,0,0]

英文:

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]

huangapple
  • 本文由 发表于 2016年11月22日 15:09:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/40735738.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定