英文:
Go map lookup returns copy of the element?
问题
似乎Go语言的map查找返回的是元素的副本。在语言规范中似乎找不到对此的描述。我写了一个如下的程序:
type T struct { n int }
m := make(map[string]T)
t := T{123}
m["123"] = t
t0 := m["123"]
t1 := m["123"]
t0.n = 456
t1.n = 789
fmt.Println(t, t0, t1)
我得到的输出是:{123} {456} {789}。看起来每次返回的都是元素的副本。
英文:
It seems like Go's map lookup returns a copy of the element. Can't seem to find this described in the language spec. I wrote a program as below:
type T struct { n int }
m := make(map[string]T)
t := T{123}
m["123"] = t
t0 := m["123"]
t1 := m["123"]
t0.n = 456
t1.n = 789
fmt.Println(t, t0, t1)
I got the output as: {123} {456} {789}. Looks like every time a copy of the element is returned?
答案1
得分: 8
Go语言不会传递引用,它要么传递值,在赋值时进行复制,要么传递指针,此时复制的是指针,实际上相当于传递了引用。
假设我们有以下结构体:
type Foo struct {
Bar string
}
如果我们创建一个值类型的映射,例如:
m := map[string]Foo{}
那么映射的访问会返回一个Foo的副本,或者是一个零值的Foo:
m["x"] = Foo{"hello"}
y := m["x"]
此时,y
是一个与映射中对象不同的对象,所以修改y
的Bar
字段不会影响映射中的对象。
但是,如果我们将映射创建为指针类型的映射:
m := map[string]*Foo{}
然后进行访问:
m["x"] = &Foo{"bar"}
y := m["x"]
此时,y
是指向映射中相同对象的指针。我们可以修改y
的Bar
字段,这将影响映射中的对象:
y.Bar = "wat"
fmt.Println(m["x"].Bar)
// 输出 "wat"
英文:
Go does not pass references, ever. It either passes values, making copies on assignment, or these values can be pointers, in which case the copy is of a pointer, which is practically a reference.
So let's say we have
type Foo struct {
Bar string
}
if we make a map of values, i.e.
m := map[string]Foo{}
then map accesses return a copy of a Foo, or a zero valued Foo:
m["x"] = Foo{"hello"}
y := m["x"]
y
is now a different object than what's in the map, so changing its Bar
won't affect the object in the map.
But, if we make the map a map of pointers:
m := map[string]*Foo{}
and then access it:
m["x"] = &Foo{"bar"}
y := m["x"]
y is now a pointer to the same object as in the map. We can change its Bar
and it will affect the map:
y.Bar = "wat"
fmt.Println(m["x"].Bar)
// Will print "wat"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论