【发布时间】:2021-02-08 02:00:39
【问题描述】:
我是 golang 的新手,所以我正在尝试从其他语言(例如 Java / JavaScript)中调整我的想法并将其应用到 golang。在大多数情况下,这非常简单。然而,当涉及到遍历地图和修改值时,我有点难过。
考虑以下示例程序:
package main
import "fmt"
type data struct {
ID string
Value string
}
func main() {
myData := make(map[string]data)
foo := data{ID: "one", Value: "oneval"}
myData["one"] = foo
foo = data{ID: "two", Value: "twoval"}
myData["two"] = foo
for _, v := range myData {
fmt.Println(v.Value)
v.Value = "kenny"
}
for _, v := range myData {
fmt.Println(v.Value)
}
}
在大多数语言中,我希望输出是:
oneval
twoval
kenny
kenny
当然不是。它是:
oneval
twoval
oneval
twoval
感谢这个 SO 答案 (How to update map values in Go),解决方案是将元素“重新分配”回地图中。哎呀,不过还好。
另一种选择是创建一个指向结构的指针映射,但这最终导致了一个相关的悖论。考虑这个更新的程序:
package main
import "fmt"
type data struct {
ID string
Value string
}
func main() {
// Now it's a map of struct pointers...
myData := make(map[string]*data)
foo := data{ID: "one", Value: "oneval"}
myData["one"] = &foo
foo = data{ID: "two", Value: "twoval"}
myData["two"] = &foo
for _, v := range myData {
fmt.Println(v.Value)
v.Value = "kenny"
}
for _, v := range myData {
fmt.Println(v.Value)
}
}
我希望输出是:
oneval
twoval
kenny
kenny
原来是这样的:
twoval
kenny
kenny
kenny
因为当变量foo被重新赋值时,映射中的相同值被重新赋值。什么????
因此,让它按预期工作的唯一方法是这样做:
package main
import "fmt"
type data struct {
ID string
Value string
}
func main() {
// Now it's a map of struct pointers...
myData := make(map[string]*data)
{
foo := data{ID: "one", Value: "oneval"}
myData["one"] = &foo
}
// Really, anything to make 'foo' go out of scope
foo := data{ID: "two", Value: "twoval"}
myData["two"] = &foo
for _, v := range myData {
fmt.Println(v.Value)
v.Value = "kenny"
}
for _, v := range myData {
fmt.Println(v.Value)
}
}
显然,必须有更好的方法。所以我问你们——StackOverflow 社区的聪明人——到底发生了什么?
【问题讨论】:
-
您应该对指针的概念有点熟悉。这确实是所有基本和预期的行为。
标签: go pointers data-structures struct