I am having trouble using structs as values in maps. The following bit of code illustrates my problem, but it does not compile, and I am unsure why.
package main
type myStruct struct {
A int
}
func main(){
structMap := make(map[int]myStruct)
structMap[0].A = 20
}
Compilation yields the following error: invalid left hand side of assignment. Why can’t I assign values to myStruct’s member A when it is used as a value in a map?
I see. So if I want to alter the struct values in a map, I first have to make a copy of the value, change the copy and reassign it to the correct key? Isn’t this a bit convoluted?
If you use pointer values in the map, you can do something like this:
package main
import (
"fmt"
)
func main() {
type structMap struct {
A int
}
m := make(map[int]*structMap)
m[0] = &structMap{A: 20}
fmt.Printf("%#v\n", *(m[0]))
v := m[0]
v.A = 21
fmt.Printf("%#v\n", *(m[0]))
}
Like @clbanning stated, that’s only if you are storing the struct by value, however If you are storing by pointer you can pretty much do what you want:
package main
import "fmt"
type myStruct struct {
A int
}
func main() {
structMap := make(map[int]*myStruct)
structMap[0] = &myStruct{A: 20}
fmt.Println(structMap[0])
structMap[0].A = 10
fmt.Println(structMap[0])
}
Just keep in mind, that you shouldn’t directly alter a map value directly anyway without first doing some sort of check like this, to avoid a nil pointer dereference panic, for example:
// First check that a myStruct object is found at key 0.
st, found := structMap[0]
// If it's found, then alter it.
if found {
st.A = 10
}
Otherwise you can see that using the following would cause that panic since there’s no map key for 1 yet:
I see how pointers give the functionality I want, though this method requires deep copy functionality as well. Thanks guys, I think I have all the information I need to proceed!