英文:
Golang updating maps and variables in an object
问题
我发现了一些行为看起来有点奇怪,如果有人能解释一下为什么会这样工作就好了。
假设我们有一个像这样的结构体/对象:
type Game struct {
players map[string]Profile
}
type Profile struct {
name string
things map[string]string
}
现在假设我们稍后调用一个Game方法,像这样:
func (g *Game) someMethod(playerName string) {
p, _ := g.players[playerName]
fmt.Println("P Name: " + p.name)
fmt.Println("Map contents: " + p.things["something"])
// 假设这里 p.name 当前等于 "bob",p.things["something"] 当前等于 "this"
p.name = "fred"
p.things["something"] = "that"
}
第一次调用someMethod()时,p.name 将等于 "bob",p.things["something"] 将等于 "this"。在更新了这些值之后,如果我们在方法内部立即再次检查它们,p.name 将等于 "fred",p.things 将等于 "that"。
然而,下一次调用这个方法时,p.things 仍然等于 "that",但是 p.name 回到了等于 "bob",而不是更新后的值 "fred"。我唯一找到的解决方法是在更新了 p.name 之后添加以下代码:
g.players[playerName] = p
所以,我的问题是,为什么在 p 对象内部更新 map 可以成功地更新它,使得下一次从 Game 对象中检索 p 时,p 的 map 有新的数据,但是当我们更新 p.name 时,它会恢复到旧的值,除非我们手动将 p 对象添加回 Game 对象的 map 中?
英文:
I've found some behavior that seems a little strange, and it would be nice if someone could explain to me why it works this way.
Let's say we have a struct / object like this:
type Game struct {
players map[string]Profile
}
type Profile struct {
name string
things map[string]string
}
Now let's say later on we call a Game method like this:
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"
}
The very first time we call someMethod(), p.name will equal "bob" and p.things["something"] will equal "this". After updating the values, if we immediately checked them again while still inside the method, p.name would equal "fred" and p.things "that".
However the next time we call this method, p.things will still equal "that" but p.name goes back to equaling "bob" instead of having the updated value of "fred". The only way I've found around this is to add this code after p.name has been updated:
g.players[playerName] = p
So, my question is, why does updating the map within the p object successfully update it so the next time we retrieve p from the Game object, p's map has the new data, but when we update p.name it reverts to the old value unless we manually add the p object back to the Game object's map?
答案1
得分: 2
someMethod
中的p
是profile结构体的一个副本。如果你想要在map中更新profile,你需要使用一个指针,并且使用类型为map[string]*Profile
的map。
至于p.things
,虽然p
是结构体的一个副本,但是map本身包含对底层数据的引用。换句话说,你不需要一个指向map的指针来操作它的内容,而且很少使用指向map的指针。
英文:
p
within someMethod
is a copy of the profile struct. If you want to update the profile within the map, you will need to use a pointer, and a map of type map[string]*Profile
As for p.things
, even though p
is a copy of the struct, the map itself contains a reference to the underlying date. In other words, you don't need a pointer to a map to manipulate it's contents, and you rarely use a pointer to a map.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论