28

Why do we have to first read the struct, modify it, and then write it back to the map? Am I missing some kind of implied hidden cost in modifying fields of structs in other data structures (like a map or a slice)?

Edit: I realize I can use pointers, but why is this not allowed by Go?

type dummy struct {
    a int
}
x := make(map[int]dummy)
x[1] = dummy{a:1}
x[1].a = 2
wasmup
  • 14,541
  • 6
  • 42
  • 58
kanu
  • 397
  • 1
  • 3
  • 5
  • 6
    You can make a map of pointers to a struct... – RickyA Nov 13 '16 at 20:55
  • 1
    The answers you seem to be looking for are available here: http://stackoverflow.com/questions/32751537/why-do-i-get-a-cannot-assign-error-when-setting-value-to-a-struct-as-a-value-i and here: http://stackoverflow.com/questions/17438253/access-struct-in-map-without-copying – Lucas Nov 14 '16 at 04:57

1 Answers1

47

You are storing a struct by value which means that accession of that struct in the map gives you a copy of the value. This is why when you modify it, the struct in the map remains unmutated until you overwrite it with the new copy.

As RickyA pointed out in the comment, you can store the pointer to the struct instead and this allows direct modification of the struct being referenced by the stored struct pointer.

i.e. map[whatever]*struct instead of map[whatever]struct

Corvus Crypto
  • 2,141
  • 1
  • 13
  • 14
  • 2
    I understand how pointers work, and that access gives you a copy. Perhaps I didn't frame it right, but my question is why did the designers of Go choose not to allow direct modification of struct fields? – kanu Nov 14 '16 at 04:48
  • 6
    Safety during parallelism. When you are adding elements to a hash, the language often has to copy all the values to a new (bigger) hash table in the background. If elements can be directly modified in memory, it will be impossible to keep all the copies in sync. If all update operations are forced thru "here is a new value", then it's easy to make sure both copies get updated. Without this, copying a hash would be a "stop the world" operation. – BraveNewCurrency Nov 14 '16 at 06:03
  • That makes sense, thanks! – kanu Nov 14 '16 at 16:27
  • 1
    I think this does not explain why error was thrown when trying to modify map of struct, whereas no error was thrown when modify map of string. – leogoesger Jan 29 '20 at 15:06
  • Thanks. Finding this solved a problem that has been cursing me for days. – MikeSchinkel Mar 29 '21 at 09:20
  • @BraveNewCurrency i'm not sure how all languages implement this but normally not values need to be copied, but the hashed keys of the entries need to be moved to a larger structure. – ipopa Mar 02 '23 at 19:10