我正在尝试创建一个“关联”地图。问题是 superMap 收集了 aMap 的所有值。基本上,即使我只想在每次查看时存储一个 amap 实例,我最终也会存储当前实例以及所有先前的循环。 supermap[value] = amap[value]。但是下面的代码片段存储了supermap[value] = amap. 原因是我找不到任何方法来解决这个问题。如果我在每次循环后删除 aMap 的旧值,它们supermap也会被删除。
package main
import (
"fmt"
)
func main() {
aData := map[int]string{
0: "apple",
1: "samsung",
2: "htc",
3: "sony",
}
dir := []string{"user", "doc", "bin", "src"}
aMap := make(map[int]string)
superMap := make(map[string]map[int]string)
for k, v := range dir {
aMap[k] = aData[k]
superMap[v] = aMap
}
hello(superMap)
}
func hello(superMap map[string]map[int]string) {
fmt.Printf("superMap of user is %v \n", superMap["user"])
cnt := len(superMap["user"])
if cnt > 1{
fmt.Printf("expected only one value received %v", cnt)
}
}
Run Code Online (Sandbox Code Playgroud)
正如 Arjan 在评论中所说,您需要将创建aMap移到 for 循环中。原因是因为,在您发布的原始代码中,您正在处理aMap内存中的一个实例。这意味着,仅aMap创建一个名为 的映射,并且当您将另一个变量分配给 的值时,aMap您正在分配一个引用。这意味着,任何持有引用的变量(到aMap)且状态发生突变的变量,都将在也持有该引用的所有其他变量中被观察到,因为它们都解析为内存中的同一对象。
当aMap被移动到 for/range 循环中时,这意味着aMap将创建 4 个单独的实例,并且所有实例都有自己的内存。改变其中一个的状态aMaps不会影响其他的,因为它们是内存中自己的对象。现在,如果您获取其中一个对象并使用另一个变量再次引用它,那么您最终会遇到与第一种情况相同的情况。
package main
import (
"fmt"
)
func main() {
aData := map[int]string{
0: "apple",
1: "samsung",
2: "htc",
3: "sony",
}
dir := []string{"user", "doc", "bin", "src"}
//aMap := make(map[int]string) //only one map instance is created in memory
superMap := make(map[string]map[int]string)
for k, v := range dir {
//multiple map instances are created in memory
aMap := make(map[int]string)
aMap[k] = aData[k]
superMap[v] = aMap
}
hello(superMap)
}
func hello(superMap map[string]map[int]string) {
fmt.Printf("superMap of user is %v \n", superMap["user"])
cnt := len(superMap["user"])
if cnt > 1 {
fmt.Printf("expected only one value received %v", cnt)
}
}
Run Code Online (Sandbox Code Playgroud)