Dictionary 初始化go结构中的深度映射嵌套

Dictionary 初始化go结构中的深度映射嵌套,dictionary,go,struct,Dictionary,Go,Struct,要在结构中初始化映射,应执行以下操作: someStruct.nestedMap = make(map[int8]int8) 但是,如果您有这样的代码结构,您应该怎么做: type Base struct { base map[int8]uint64 } type Middle struct { baseObjects map[int8]Base } type Top struct { middleObjects map[int8]Middle } 在这里,我们总

要在结构中初始化映射,应执行以下操作:

someStruct.nestedMap = make(map[int8]int8)
但是,如果您有这样的代码结构,您应该怎么做:

type Base struct {
    base map[int8]uint64
}

type Middle struct {
    baseObjects map[int8]Base
}

type Top struct {
    middleObjects map[int8]Middle
}
在这里,我们总共有3个结构,每个结构都有一个作为键的结构。
如何初始化它,并使其准备就绪?

只需使用空映射作为其
middleObjects
属性的值初始化最顶层的结构
Top
,调用空映射上的任何索引将返回映射所持有类型的零值

package main

import (
    "fmt"
)

type Base struct {
    base map[int8]uint64
}

type Middle struct {
    baseObjects map[int8]Base
}

type Top struct {
    middleObjects map[int8]Middle
}

func main() {
    top := Top{
        middleObjects: make(map[int8]Middle),
    }

    // Outputs: "Top: {map[]}"
    fmt.Printf("Top: %v\n", top)

    // Outputs: "Base element: 0"
    fmt.Printf("Base element: %v\n", top.middleObjects[5].baseObjects[3].base[0])
}
运行示例


编辑:

您还可以使用几个元素初始化
Top
结构,在任何情况下,这取决于初始化时需要每个映射包含多少元素:

func main() {
    top := Top{
        middleObjects: map[int8]Middle{
            0: Middle{
                baseObjects: map[int8]Base{
                    0: Base{
                        base: map[int8]uint64{
                            0: 1234,
                        },
                    },
                },
            },
        },
    }

    // After that you have to add one by one
    top.middleObjects[5] = Middle{
        baseObjects: map[int8]Base{
            0: Base{
                base: map[int8]uint64{
                    0: 123456,
                },
            },
        },
    }
    // If there's a middleObject with that index
    top.middleObjects[0].baseObjects[1] = Base{
        base: map[int8]uint64{
            0: 1111,
        },
    }

    // Outputs: "Base element: 1234"
    fmt.Printf("Base element: %v\n", top.middleObjects[0].baseObjects[0].base[0])
    // Outputs: "Base element: 123456"
    fmt.Printf("Base element: %v\n", top.middleObjects[5].baseObjects[0].base[0])
    // Outputs: "Base element: 1111"
    fmt.Printf("Base element: %v\n", top.middleObjects[0].baseObjects[1].base[0])

    top.middleObjects[0].baseObjects[0].base[0] = 2222
    // Outputs: "Base element: 2222"
    fmt.Printf("Base element: %v\n", top.middleObjects[0].baseObjects[0].base[0])
}

运行示例

实际上,您想要的是一个具有默认值的映射,该值不是零值,而是一个可以使用的值,在本例中,是一个生成的映射

在讨论解决方案之前,实际上有一个关于转到此处的问题:

出于各种原因,如果结构存储在映射中,则Go now不支持将其指定给结构的字段

要解决此问题,需要使用指向该结构的指针,并将指针存储在映射中。因此,您的数据结构需要进行如下更改:

type Base struct {
    base map[int8]uint64
}

type Middle struct {
    baseObjects map[int8]*Base
}

type Top struct {
    middleObjects map[int8]*Middle
}
核心逻辑是:一个不确定的价值地图。Go不支持普通地图,但我们可以扩展它,使用方法来包装它

func (t Top) Get(i int8) *Middle {
    x, ok := t.middleObjects[i]
    if !ok {
        v := NewMiddle()
        t.middleObjects[i] = v
        return v
    }

    return x
}

func (m Middle) Get(i int8) *Base {
    x, ok := m.baseObjects[i]
    if !ok {
        v := NewBase()
        m.baseObjects[i] = v
        return v
    }

    return x
}
当我们试图获取一个值时,我们首先检查它是否存在。如果不存在,则返回一个新构造的值,如果它确实存在,则返回该值

用法:

t.Get(8).Get(9).base[10] = 14

操场示例:

分别编写
NewTop
NewMiddle
NewBase
。你尝试过什么?遇到了什么问题?你能写一个简单的例子吗?我不太明白。你有什么问题?当尝试什么的时候?坦白地说,我有一个问题,就是不理解如何正确地编写代码。我知道我可能应该创建各自结构的具体对象,但如何正确编写呢?是的,但如果我尝试像这样赋值和整型:
top.middleObjects[5].baseObjects[3].base[0]=10
,它会惊慌失措:赋值到nil映射中的条目。如果我尝试制作这样的映射:
top.middleObjects[5].baseObjects[3].base=make(map[int8]uint64)
它会这样崩溃:无法在映射中指定结构字段top.middleObjects[5].baseObjects[3].base非常感谢您的帮助。我来看看你提供的例子。我真的很感谢你的例子。我们将考虑到这一点。