在地图中访问结构(无复制)

Assuming the following

type User struct {
    name string
}

users := make(map[int]User)

users[5] = User{"Steve"}

Why isn't it possible to access the struct instance now stored in the map?

users[5].name = "Mark"

Can anyone shed some light into how to access the map-stored struct, or the logic behind why it's not possible?

Notes

I know that you can achieve this by making a copy of the struct, changing the copy, and copying back into the map -- but that's a costly copy operation.

I also know this can be done by storing struct pointers in my map, but I don't want to do that either.

The fundamental problem is that you can't take the address of something in a map. You might think the compile would re-arrange users[5].name = "Mark" into this

(&users[5]).name = "Mark"

But that doesn't compile, giving this error

cannot take the address of users[5]

This is to allow maps the freedom to re-order things at will to use memory efficiently.

The only way to change something actually in a map is to assign to it, i.e.

t := users[5]
t.name = "Mark"
users[5] = t

So I think you either have to live with the copy above, or live with storing pointers in your map. Storing pointers has the disadvantage of using more memory and more memory allocations which may outweigh the copying in the above - only you and your application can tell that.

A third alternative is to use a slice - your original syntax works perfectly if you change users := make(map[int]User) to users := make([]User, 10)

I think these are restrictions introduced to simplify the map implementation.

For instance, they don't allow accessing the address of the value returned by map lookup

 fmt.Printf("Address of p[key] %p", &p["key"]) 

./map1.go:19:36: cannot take the address of p["key"]

Similarly, when we are referring the map, the value returned is returned "returned by value", if i may borrow the terminology used in function parameters, editing the returned structure does not have any impact on the contents of the map