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

时间:2013-07-03 01:12:52

标签: go

假设以下

type User struct {
    name string
}

users := make(map[int]User)

users[5] = User{"Steve"}

为什么不能访问现在存储在地图中的结构实例?

users[5].name = "Mark"

任何人都可以了解如何访问地图存储的结构,或者为什么它不可能背后的逻辑?

备注

我知道您可以通过制作结构的副本,更改副本以及复制回地图来实现这一目标 - 但这是一项代价高昂的复制操作。

我也知道这可以通过在我的地图中存储struct指针来完成,但我也不想这样做。

2 个答案:

答案 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>