如何在 golang 中创建关联映射?

The*_*hat 7 arrays go

我正在尝试创建一个“关联”地图。问题是 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)

Ral*_*veo 5

正如 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)