Golang更新对象中的映射和变量

时间:2014-07-29 01:34:37

标签: go maps

我发现了一些看起来有点奇怪的行为,如果有人可以向我解释为什么它会这样运作会很好。

我们假设我们有一个像这样的结构/对象:

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对象的地图?

1 个答案:

答案 0 :(得分:2)

p中的

someMethod是个人资料结构的副本。如果要更新地图中的配置文件,则需要使用指针和类型为map[string]*Profile的地图

至于p.things,即使p是结构的副本,地图本身也包含对基础日期的引用。换句话说,您不需要指向地图的指针来操纵它的内容,而您很少使用指向地图的指针。