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?
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"