为了账号安全,请及时绑定邮箱和手机立即绑定

带有嵌套映射 golang 的结构

带有嵌套映射 golang 的结构

Go
茅侃侃 2021-12-07 15:16:41
我是新来的,正试图弄清楚地图是如何工作的。我编写了一个小测试程序,但似乎无法让它工作。我做错了什么?package mainimport (    "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)}
查看完整描述

3 回答

?
杨魅力

TA贡献1811条经验 获得超6个赞

代码有几个问题:

  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)

}


查看完整回答
反对 回复 2021-12-07
?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

添加这个作为解决问题的不同方法:


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)

}


查看完整回答
反对 回复 2021-12-07
?
慕仙森

TA贡献1827条经验 获得超7个赞

你的方法有几个问题。

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

  • 地图返回其值的副本。所以当你拉出“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)

}


查看完整回答
反对 回复 2021-12-07
  • 3 回答
  • 0 关注
  • 190 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信