2016-01-24 156 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