Unable to assign values to struct members in maps

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?

Hey @fellerts,

You need to actually assign your map key to a myStruct type, for example:

package main

import "fmt"

type myStruct struct {
	A int
}

func main() {
	structMap := make(map[int]myStruct)
	structMap[0] = myStruct{A: 20}
	fmt.Println(structMap)
}
1 Like

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]))
}
2 Likes

Hey @fellerts,

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:

structMap[1].A = 10
3 Likes

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! :slight_smile:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.