【问题标题】:Golang Map struct in another oneGolang Map 结构在另一个
【发布时间】:2014-05-27 21:28:24
【问题描述】:

我是 golang 的新手,在这种情况下,我有一个 map [string],它有一个结构。 此时一切正常。

但我想要一个 map[string],我可以在其中同时访问另一个具有自结构的 map[string]。

这是我正在尝试使用的代码。

type myStruct struct{
    atrib1       string
    atrib2       string 

}

var apiRequest map[string] map[string]myStruct

我想要访问这样的东西:

func main() {
    apiRequest = make(map[string] map[string]myStruct)

    apiKeyTypeRequest["Key"]["MyFirstOption"].atrib1 = "first Value first op" 
    apiKeyTypeRequest["Key"]["MyFirstOption"].atrib2 = "second Value first op" 
    apiKeyTypeRequest["Key"]["MysecondtOption"].atrib1 = "first Value second op" 

}

【问题讨论】:

  • 需要手动为外层map的每个key创建一个map。
  • 我刚刚创建了一个小包来将结构映射到结构,它处于早期阶段,我正在使用它学习 golang,但它可能对你有一些用处:github.com/gdperkins/gomap

标签: go


【解决方案1】:

在地图中使用地图的另一种方法是使用单个map[mapKey],其中mapKey 是一个结构:

type mapKey struct {
    Key    string
    Option string
}

好处是您在搜索myStruct 时只需进行一次查找,并且您只需创建一个地图。
不利的一面是,如果您需要能够获得该选项 map[string]myStruct 映射,因为它不存在。此外,您无法检查某个键是否存在,因为键和选项是成对存在的。

工作示例:

package main

import "fmt"

type myStruct struct {
    atrib1 string
    atrib2 string
}

type mapKey struct {
    Key    string
    Option string
}

func main() {
    apiKeyTypeRequest := make(map[mapKey]myStruct)

    apiKeyTypeRequest[mapKey{"Key", "MyFirstOption"}] = myStruct{"first Value first op", "second Value first op"}
    apiKeyTypeRequest[mapKey{"Key", "MysecondtOption"}] = myStruct{atrib1: "first Value second op"}

    fmt.Printf("%+v\n", apiKeyTypeRequest)
}

游乐场: http://play.golang.org/p/tGd7ja7QI2

【讨论】:

  • 这不允许您单独通过外部映射键进行查找,并且具有为每个元素复制顶级键的内存开销。这基本上就像将两个键连接到一个映射中。
  • @Not_a_Golfer:是的。我已经在我的缺点中提到了这一点。好吧,不是键字符串重复部分,而是我认为通过消除多映射内存开销来平衡它的重要性。它是一种替代方法,在某些情况下很有用。
【解决方案2】:

要扩展之前的答案,必须声明和实例化每个映射(以及映射末尾的结构),这意味着您需要实例化“外部”映射

mapOfMaps := make(map[string]map[string]myStruct)

以及您拥有的每个键的“内部”映射。

mapOfMaps[key] = make(map[string]myStruct)

您在这里遇到的明显问题是如何动态检查mapOfMaps[key] 是否已被实例化?您可以使用以下语法来执行此操作:

if _, ok := mapOfMaps[key]; !ok {
    mapOfMaps[key] = make(map[string]myStruct)
}

此语法检查mapOfMaps 是否已经具有该键的实例化值,如果没有则实例化它。同样,您可以使用相同的语法来实例化您正在使用的结构,方法是检查 mapOfMaps[key][key2] 是否已被实例化。

if _, ok := mapOfMaps[key][key2]; !ok {
    mapOfMaps[key][key2] = new(myStruct)
}

现在你可以通过调用结构体的两个键和一个属性来访问结构体

fmt.Println(mapOfMaps[key][key2].atrib1)

【讨论】:

    【解决方案3】:

    正如@FUZxxl 所说,您需要为每个外部地图初始化子地图,但它有一个简写语法:

    type myStruct struct {
        atrib1 string
        atrib2 string
    }
    
    func main() {
        var myMap = map[string]map[string]myStruct{
            "foo": {
                "bar": {attrib1: "a", attrib2: "b"},
                "baz": {"c", "d"}, //or by order...
            },
            "bar": {
                "gaz": {"e", "f"},
                "faz": {"g", "h"},
            },
        }
    
        fmt.Println(myMap["foo"]["bar"].atrib1)
        fmt.Println(myMap["bar"]["gaz"].atrib2)
    }
    

    【讨论】:

      猜你喜欢
      • 2023-02-03
      • 2022-01-02
      • 2019-05-12
      • 2016-07-30
      • 1970-01-01
      • 1970-01-01
      • 2013-10-17
      • 2018-02-10
      相关资源
      最近更新 更多