【问题标题】:How to create an associative map in golang?如何在 golang 中创建关联地图?
【发布时间】:2014-04-15 01:40:02
【问题描述】:

我正在尝试创建一个“关联”地图。问题是 superMap 收集了 aMap 的所有值。 基本上,即使我只想在每个外观上存储一个 amap 实例,我最终也会存储当前实例以及所有先前的循环。 supermap[value] = amap[value] 。但是下面的 sn-p 存储 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

【问题讨论】:

  • aMap 创建移动到 for 循环中
  • @Arjan 这是一个陷阱,不是吗?我想知道为什么当你重新初始化地图时它可以工作,但当你删除它时它却不起作用。

标签: arrays go


【解决方案1】:

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

【讨论】:

  • 我不知道地图是如何真正存储在内存中的。我想知道这个解决方案是否不会导致内存泄漏。
  • 由于 Go 是垃圾收集器,使用这样的典型代码不会出现内存泄漏问题。你不必太关心 Go 的内存细节。重要的是在处理引用、值和指针时识别。
猜你喜欢
  • 2019-11-25
  • 1970-01-01
  • 2016-05-23
  • 1970-01-01
  • 2020-01-16
  • 1970-01-01
  • 1970-01-01
  • 2011-07-31
  • 1970-01-01
相关资源
最近更新 更多