假设以下
type User struct {
name string
}
users := make(map[int]User)
users[5] = User{"Steve"}
为什么不能访问现在存储在地图中的结构实例?
users[5].name = "Mark"
任何人都可以了解如何访问地图存储的结构,或者为什么它不可能背后的逻辑?
我知道您可以通过制作结构的副本,更改副本以及复制回地图来实现这一目标 - 但这是一项代价高昂的复制操作。
我也知道这可以通过在我的地图中存储struct指针来完成,但我也不想这样做。
答案 0 :(得分:34)
根本问题在于你不能在地图中获取某些东西的地址。您可能认为编译会将users[5].name = "Mark"
重新安排到此
(&users[5]).name = "Mark"
但是这没有编译,给出了这个错误
cannot take the address of users[5]
这是为了让地图能够自由地重新排序,以便有效地使用内存。
在地图中实际更改内容的唯一方法是分配给它,即
t := users[5]
t.name = "Mark"
users[5] = t
所以我认为您要么必须使用上面的副本,要么在地图中存储指针。存储指针的缺点是使用更多的内存和更多的内存分配,这可能超过上面的复制 - 只有你和你的应用程序可以告诉你。
第三种方法是使用切片 - 如果将users := make(map[int]User)
更改为users := make([]User, 10)
答案 1 :(得分:0)
我认为这些是为简化地图实现而引入的限制。
例如,它们不允许访问由地图查找返回的值的地址
fmt.Printf("Address of p[key] %p", &p["key"])
./ map1.go:19:36:无法使用p [“ key”]
的地址类似地,当我们引用地图时,返回的值将“按值返回”,如果我可以借用函数参数中的术语,则编辑返回的结构不会对地图的内容产生任何影响< / p>