2016-01-24 239 views
0

嗨,我是新来的,并试图弄清楚地图如何工作。 我已经编写了一个小测试程序,似乎无法让它工作。 我做错了什么?嵌套地图结构golang

package main 

import (
    "fmt" 
) 

type Stats struct { 
    cnt  int 
    category map[string]Events 
} 

type Events struct { 
    cnt int 
    event map[string]Event 
} 

type Event struct { 
    value int64 
} 

func main() { 

    stats := new(Stats) 
    stats.cnt = 33 
    stats.category["aa"].cnt = 66 
    stats.category["aa"].event["bb"].value = 99 

    fmt.Println(stats.cnt, stats.category["aa"].event["bb"].value) 
} 
+0

'stats.category [ “AA”]'应该是地图上的字符串切换到事件片段,但您正在尝试将其赋值为66. – verygoodsoftwarenotvirus

回答

2

有几个问题的代码: 1.地图需要使用make函数初始化。目前他们没有 2.从map返回值是不可寻址的,这是因为如果map增长,它需要重新定位,这会导致内存地址改变。因此,我们需要从地图明确提取值到变量,更新它并将其赋值。 3.使用指针

我已经更新了解决方案,以显示更新它返回的值并将其分配回去和指针。

http://play.golang.org/p/lv50AONXyU

package main 

import (
    "fmt" 
) 

type Stats struct { 
    cnt  int 
    category map[string]Events 
} 

type Events struct { 
    cnt int 
    event map[string]*Event 
} 

type Event struct { 
    value int64 
} 

func main() { 

    stats := new(Stats) 
    stats.cnt = 33 
    stats.category = make(map[string]Events) 
    e, f := stats.category["aa"] 
    if !f { 
     e = Events{} 
    } 
    e.cnt = 66 

    e.event = make(map[string]*Event) 
    stats.category["aa"] = e 
    stats.category["aa"].event["bb"] = &Event{} 
    stats.category["aa"].event["bb"].value = 99 

    fmt.Println(stats) 
    fmt.Println(stats.cnt, stats.category["aa"].event["bb"].value) 
} 
+0

感谢您的解决方案,这正是我所期待的。 –

0

您的方法有几个问题。

  • 您并未初始化您的地图。你需要先创建它们。

  • 地图返回其值的副本。所以当你拉出“aa”并修改它时,你会得到一个“aa”的副本,然后将其改掉,然后扔掉。你需要把它放回地图,或使用指针。

这是Play的一个工作示例(非指针版本)。
注意地图的构造以及修改值时重新分配给地图。

package main 

import (
    "fmt" 
) 

type Stats struct { 
    cnt  int 
    category map[string]Events 
} 

type Events struct { 
    cnt int 
    event map[string]Event 
} 

type Event struct { 
    value int64 
} 

func main() { 
    stats := &Stats{category: map[string]Events{}} 
    stats.cnt = 33 
    tmpCat, ok := stats.category["aa"] 
    if !ok { 
     tmpCat = Events{event: map[string]Event{}} 
    } 
    tmpCat.cnt = 66 
    tmpEv := tmpCat.event["bb"] 

    tmpEv.value = 99 
    tmpCat.event["bb"] = tmpEv 
    stats.category["aa"] = tmpCat 

    fmt.Println(stats.cnt, stats.category["aa"].event["bb"].value) 
} 
1

添加此作为一种不同的方法的问题:

type Stats struct { 
    cnt  int 
    categories map[string]*Events 
} 

func (s *Stats) Category(n string) (e *Events) { 
    if s.categories == nil { 
     s.categories = map[string]*Events{} 
    } 
    if e = s.categories[n]; e == nil { 
     e = &Events{} 
     s.categories[n] = e 
    } 
    return 
} 

type Events struct { 
    cnt int 
    events map[string]*Event 
} 

func (e *Events) Event(n string) (ev *Event) { 
    if e.events == nil { 
     e.events = map[string]*Event{} 
    } 
    if ev = e.events[n]; ev == nil { 
     ev = &Event{} 
     e.events[n] = ev 
    } 
    return 
} 

type Event struct { 
    value int64 
} 

func main() { 
    var stats Stats 
    stats.cnt = 33 
    stats.Category("aa").cnt = 66 
    stats.Category("aa").Event("bb").value = 99 

    fmt.Println(stats) 
    fmt.Println(stats.cnt, stats.Category("aa").Event("bb").value) 
} 

playground