Go: cannot assign to struct field in map

One of the surprising things beginners realize about Go is that maps are passed by reference. This means if a map is modified in the function it was passed to, the caller will also see the changes.

package main

import "fmt"

func f(m map[int]int) {
	m[0] = 1
}

func main() {
	m := make(map[int]int)
	m[0] = 0
	fmt.Println(m) // prints map[0:0]
	f(m)
	fmt.Println(m) // prints map[0:1]
}

However, if m is a map[int]node, m[0] is not a reference to a node but the value stored in memory. This means you can’t modify the fields of m[0] directly, as m[0] is just a copy of the value.

package main

type node struct {
	val int
}

func main() {
	m := make(map[int]node)
	m[0] = node{val: 1}
	m[0].val = 2
}

stderr-> cannot assign to struct field m[0].val in map

To resolve this, you need to first assign map[key] to a variable, modify it, and then put it back into the map. In the code below, since m0 is not reassigned to m, m[0].val remains unchanged.

package main

import "fmt"

type node struct {
	val int
}

func main() {
	m := make(map[int]node)
	m[0] = node{val: 0}
	m[1] = node{val: 1}
	fmt.Println(m) // prints map[0:{0} 1:{1}]
	m0 := m[0]
	m0.val = 2
	m1 := m[1]
	m1.val = 3
	m[1] = m1
	fmt.Println(m) // prints map[0:{0} 1:{3}]
}

There is a Go proposal from to allow developers to be able to modify map elements directly, however it is still in progress.

More:
1. Why it matters that map values are unaddressable in Go
2. Go maps in action