Reputation: 485
I've been trying to update a map variable inside a struct but with no luck.
I expected that maps in Golang are passed by reference and hence assigning one reference to another should work but that's not the case.
I might be missing something obvious here, and if that's the case, apologies!
package main
import (
"fmt"
)
type Foo struct {
t map[string]interface{}
}
func (F Foo) Set(ta map[string]interface{}) {
F.t = ta
}
func (F Foo) Get() map[string]interface{} {
return F.t
}
func main() {
t := make(map[string]interface{})
t["t"] = "sf"
t["array"] = []int{1, 2, 3}
fmt.Println(t) // prints map[t:sf array:[1 2 3]]
var f Foo
f.Set(t)
// why the following?
fmt.Println(f.t) //prints map[]
f.t = t
fmt.Println(f.t) //prints map[t:sf array:[1 2 3]]
}
Playground: https://play.golang.org/p/i1ESV1BdjGQ
Upvotes: 1
Views: 1095
Reputation: 3734
Basically, you need a pointer receiver on your Set
method to be able to change the state of your structure.
Methods with pointer receivers can modify the value to which the receiver points. Since methods often need to modify their receiver, pointer receivers are more common than value receivers.
Get
should also have a pointer receiver for consistency:
Next is consistency. If some of the methods of the type must have pointer receivers, the rest should too, so the method set is consistent regardless of how the type is used. See the section on method sets for details.
See a tour of go for more examples.
Here is a fix of your code:
package main
import (
"fmt"
)
type Foo struct {
t map[string]interface{}
}
func (F *Foo) Set(ta map[string]interface{}) {
F.t = ta
}
func (F *Foo) Get() map[string]interface{} {
return F.t
}
func main() {
t := make(map[string]interface{})
t["t"] = "sf"
t["array"] = []int{1, 2, 3}
fmt.Println(t)
var f Foo
f.Set(t)
fmt.Println(f.Get()) //prints map[t:sf array:[1 2 3]]
f.t = t
fmt.Println(f.Get()) //prints map[t:sf array:[1 2 3]]
}
Outputs
map[t:sf array:[1 2 3]]
map[t:sf array:[1 2 3]]
map[t:sf array:[1 2 3]]
Try it yourself here
Upvotes: 2