英文:
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)
对于那些只在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)
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
,创建一个附加到 s
的 foo
的副本。当你打印 s
时,你打印的是新创建的(当它被初始化为0时)附加到 s
的 foo
,而不是修改后的 foo
数组。
当你交换 s = append(s, foo)
和 foo.A[0] = 42
时,你做的是同样的事情,但这次你看到了你期望的结果,因为你将带有42的 foo
数组复制到了 s
中。如果你再次修改 foo
,fmt.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]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论