具有嵌套地图 golang 的结构
structure with nested maps 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)
}
您的方法存在一些问题。
您没有初始化地图。您需要先创建它们。
映射 return 其值的副本。因此,当您取出 "aa" 并对其进行修改时,您将获得 "aa" 的副本,更改它,然后将其丢弃。你需要把它放回地图里,或者用指针。
这是 Play 上的工作示例(non-pointer 版本)。
注意映射的构造,以及修改值时 re-assignment 返回映射。
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)
}
代码有几个问题:
地图需要使用make函数初始化。目前他们是零
Return 来自 map 的值是 non-addressable,这是因为如果 map 正在增长,它需要重新定位,这将导致内存地址发生变化。因此,我们需要明确地从映射中提取值到变量,更新它并重新分配它。
使用指针
我已经更新了解决方案以显示更新后的返回值和分配给它的指针。
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)
}
将此添加为解决问题的不同方法:
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)
}
您好,我是新来的,正在尝试了解地图的工作原理。 我编写了一个小测试程序,但似乎无法运行。 我做错了什么?
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)
}
您的方法存在一些问题。
您没有初始化地图。您需要先创建它们。
映射 return 其值的副本。因此,当您取出 "aa" 并对其进行修改时,您将获得 "aa" 的副本,更改它,然后将其丢弃。你需要把它放回地图里,或者用指针。
这是 Play 上的工作示例(non-pointer 版本)。
注意映射的构造,以及修改值时 re-assignment 返回映射。
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)
}
代码有几个问题:
地图需要使用make函数初始化。目前他们是零
Return 来自 map 的值是 non-addressable,这是因为如果 map 正在增长,它需要重新定位,这将导致内存地址发生变化。因此,我们需要明确地从映射中提取值到变量,更新它并重新分配它。
使用指针
我已经更新了解决方案以显示更新后的返回值和分配给它的指针。
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)
}
将此添加为解决问题的不同方法:
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)
}