2016-01-24 4 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 [ "аа"]' должна быть карта строки для фрагмента событий, но вы пытаетесь присвоить ему значение 66. – verygoodsoftwarenotvirus

ответ

2

Есть несколько проблем, с кодом: 1. Карта должна быть инициализирована с помощью функции сделать. В настоящее время они ноль 2. Возвращаемое значение с карты не адресуется, потому что, если карта растет, ее необходимо переместить, что приведет к изменению адреса памяти. Следовательно, нам нужно явно извлечь значение из карты в переменную, обновить ее и назначить обратно. 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

Смежные вопросы