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

7

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

Play


2
aMap 的创建移入for循环中。 - Arjan
@Arjan 这是一个陷阱,不是吗?我在想为什么当你重新初始化地图时它能够工作,但是当你删除它时却不能。 - The user with no hat
1个回答

5
正如Arjan在评论中所说,你需要将aMap的创建移到for循环中。原因是,在你发布的原始代码中,你正在处理内存中的一个aMap实例。这意味着只创建了一个名为aMap的地图,当你将另一个变量分配给aMap的值时,你正在分配一个引用。这意味着,任何保存引用(指向aMap)的变量,在状态被改变时,所有其他变量也保存引用,因为它们都解析到内存中的同一个对象。
aMap移动到for/range循环中时,这意味着将创建4个单独的aMap实例,每个实例都有自己的内存。改变其中一个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)
    }
}

我之前并不知道地图是如何在内存中存储的。我在想这个解决方案是否会导致内存泄漏。 - The user with no hat
由于Go是垃圾回收的,您不必担心像这样的典型代码中出现内存泄漏的问题。您不必过多关注Go的内存细节。重要的是要认识到何时处理引用、值和指针。 - Ralph Caraveo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接