我发现了一些看起来有点奇怪的行为,如果有人可以向我解释为什么它会这样运作会很好。
我们假设我们有一个像这样的结构/对象:
type Game struct {
players map[string]Profile
}
type Profile struct {
name string
things map[string]string
}
现在让我们稍后说我们称这样的游戏方法:
func (g *Game) someMethod(playerName string) {
p, _ := g.players[playerName]
fmt.Println("P Name: " + p.name)
fmt.Println("Map contents: " + p.things["something"])
// let's assume here p.name currently equals "bob" and p.things["something"] currently equals "this"
p.name = "fred"
p.things["something"] = "that"
}
我们第一次调用someMethod()时,p.name将等于" bob"和p.things ["某事"]将等于"这"。更新值后,如果我们在方法内部立即再次检查它们,p.name将等于" fred"和p.things"那"。
然而,下次我们称这种方法时,p .things仍然等于""但p.name又回到了等同于" bob"而不是更新的" fred"的值。我发现的唯一方法是在更新p.name后添加此代码:
g.players[playerName] = p
所以,我的问题是,为什么更新p对象中的地图会成功更新它,所以下次我们从Game对象中检索p时,p的地图会有新数据,但是当我们更新p时。命名它还原为旧值,除非我们手动将p对象添加回Game对象的地图?
答案 0 :(得分:2)
p
中的 someMethod
是个人资料结构的副本。如果要更新地图中的配置文件,则需要使用指针和类型为map[string]*Profile
的地图
至于p.things
,即使p
是结构的副本,地图本身也包含对基础日期的引用。换句话说,您不需要指向地图的指针来操纵它的内容,而您很少使用指向地图的指针。