简体   繁体   English

如何在go中使用空结构值制作地图

[英]How to make map with empty struct values in go

How to make go map of such structure:如何制作这种结构的地图:


{
    "A": [
        {
            "name": "My name",
            "desc": "aaaa",
            "sub": [] //empty
        },
        {
            "name": "Loc",
            "desc": "bbbb"
            "sub": [
              {
                  "name": "xxxxx",
                  "desc": "aaaa",
              },
              {
                  "name": "yyyyy",
                  "desc": "aaaa",
              },
            ] 
        },
    ],
    "B": [
        {
            "name": "My name b",
            "desc": "cccc",
            "sub": [] //empty
        },
        {
            "name": "tyty",
            "desc": "ffff"
            "sub": [
                {
                    "name": "rrrrrr",
                    "desc": "descrition",
                }
            ] 
        },
    ]
}

I tried to do that but i am not getting it.我试图这样做,但我不明白。 How make empty struct/array and how make struct in struct?如何制作空结构/数组以及如何在结构中制作结构?


    type myStruct struct {
        Name string `json:"name"`
        Desc string `json:"desc"`
        // ?? Sub myStruct `json:"sub"`
    }

    m := map[string]interface{}{
        "A": []myStruct{
            {"My name", "aaaa", []???? },
            {"Loc", "bbbb", ??? },
        },
    }

There's some typo's in your original JSON, but using online services like JSON-to-Go yields the following struct definition:您的原始 JSON 中存在一些拼写错误,但使用JSON-to-Go等在线服务会产生以下结构定义:

type AutoGenerated struct {
    A []struct {
        Name string        `json:"name"`
        Desc string        `json:"desc"`
        Sub  []interface{} `json:"sub"`
    } `json:"A"`
    B []struct {
        Name string        `json:"name"`
        Desc string        `json:"desc"`
        Sub  []interface{} `json:"sub"`
    } `json:"B"`
}

FYI, below is the cleaned/syntax-corrected version of your JSON I used:仅供参考,以下是我使用的 JSON 的清理/语法更正版本:

{
    "A": [
        {
            "name": "My name",
            "desc": "aaaa",
            "sub": []
        },
        {
            "name": "Loc",
            "desc": "bbbb",
            "sub": [
              {
                  "name": "xxxxx",
                  "desc": "aaaa"
              },
              {
                  "name": "yyyyy",
                  "desc": "aaaa"
              }
            ]
        }
    ],
    "B": [
        {
            "name": "My name b",
            "desc": "cccc",
            "sub": []
        },
        {
            "name": "tyty",
            "desc": "ffff",
            "sub": [
                {
                    "name": "rrrrrr",
                    "desc": "descrition"
                }
            ] 
        }
    ]
}

You can use the following structure type definition which will work.您可以使用以下有效的结构类型定义。 It avoids the interface{} which is not handy to use to access data.它避免了不方便用于访问数据的interface{} Change the class names to your liking.根据您的喜好更改类名称。

package main

import (
    "fmt"
    "encoding/json"
)

var str = `{
    "A": [
        {
            "name": "My name",
            "desc": "aaaa",
            "sub": []
        },
        {
            "name": "Loc",
            "desc": "bbbb",
            "sub": [
              {
                  "name": "xxxxx",
                  "desc": "aaaa"
              },
              {
                  "name": "yyyyy",
                  "desc": "aaaa"
              }
            ]
        }
    ],
    "B": [
        {
            "name": "My name b",
            "desc": "cccc",
            "sub": []
        },
        {
            "name": "tyty",
            "desc": "ffff",
            "sub": [
                {
                    "name": "rrrrrr",
                    "desc": "descrition"
                }
            ] 
        }
    ]
}`

// DescLeaf is leaf of description tree
type DescLeaf struct {
    Name string `json:"name"`
    Desc string `json:"desc"`
}

// DescNode is node of description tree
type DescNode struct {
    Name string `json:"name"`
    Desc string `json:"desc"`
    Sub []DescLeaf `json:"sub"` 
}

// DescRoot is root of description tree
type DescRoot struct {
    A []DescNode `json:"A"`
    B []DescNode `json:"B"`
}

func main() {
    var r DescRoot

    err := json.Unmarshal([]byte(str), &r)
    if err != nil {
        fmt.Println("error:", err)
    } else {
        fmt.Println("done:", r)
    }
}

Outputs产出

done: {[{My name aaaa []} {Loc bbbb [{xxxxx aaaa} {yyyyy aaaa}]}] [{My name b cccc []} {tyty ffff [{rrrrrr descrition}]}]}

Based on the example JSON, it appears that you are attempting to create a recursive JSON structure.根据示例 JSON,您似乎正在尝试创建递归 JSON 结构。 Recursive JSON (and recursive structs) are both very useful, but you have to make sure that you properly build them, or you can run into situations where the structure can not be created in memory.递归 JSON(和递归结构)都非常有用,但您必须确保正确构建它们,否则您可能会遇到无法在内存中创建结构的情况。

Let us take a simple example:让我们举一个简单的例子:

type example struct {
    itemOne int64
    subElement example
}

When the program begins to create the struct in memory, it needs to figure out how large it needs to make it.当程序开始在内存中创建结构时,它需要弄清楚它需要多大。 That process goes as such:这个过程是这样的:

  1. figure out how large to make itemOne.计算出 itemOne 的大小。
    • Add 8 bytes to the allocation space.向分配空间添加 8 个字节。 (Total: 8) (总计:8)
  2. figure out how large to make subElement.弄清楚制作子元素有多大。
    1. figure out how large to make subElement-itemOne弄清楚使 subElement-itemOne 有多大
      • Add 8 bytes to the allocation space.向分配空间添加 8 个字节。 (Total: 16) (总计:16)
    2. figure out how large to make subElement-subElement计算出 subElement-subElement 有多大
      1. etc.等等

This process would continue forever until either 1: a stack overflow occurs in the program calculating the memory size, or 2: the total required memory was too large for the program.这个过程将永远持续下去,直到 1:计算内存大小的程序发生堆栈溢出,或 2:程序所需的总内存太大。

In the case of Go, this situation actually has detection built in specifically, so the second step is actually never run.在 Go 的情况下,这种情况实际上已经专门内置了检测,所以第二步实际上永远不会运行。 returning ./prog.go:7:6: invalid recursive type example for example.返回./prog.go:7:6: invalid recursive type example示例。

The solution to this problem is to create a struct where the calculator knows the exact size of everything that it has to add to the struct.这个问题的解决方案是创建一个结构,其中计算器知道它必须添加到结构中的所有内容的确切大小。 To do this, we take advantage of the fact that all structs have in common the size of the pointer to their location in memory.为此,我们利用了这样一个事实,即所有结构都具有指向它们在内存中的位置的指针的大小。

type example struct {
    itemOne int64
    subElement *example
}

The addition of that single asterisk makes the recursive process from before finite.添加那个星号使得之前的递归过程是有限的。

  1. figure out how large to make itemOne.计算出 itemOne 的大小。
    • Add 8 bytes to the allocation space.向分配空间添加 8 个字节。 (Total: 8) (总计:8)
  2. figure out how large to make subElement pointer .弄清楚使 subElement指针有多大。
    • Add 8 bytes to the allocation space (Total 16)向分配空间添加 8 个字节(共 16 个)
  3. Clean up and allocate 16 bytes.清理并分配 16 个字节。

The values are then set to their defaults.然后将这些值设置为其默认值。 Integers are set to zero, and pointers the nil value (also zero).整数设置为零,并指向 nil 值(也为零)。 Passing one of these into the json unmarshal would then create the exact structure you are looking for.将其中之一传递到 json unmarshal 将创建您正在寻找的确切结构。

type sub struct {
    Name string     `json:"name"`
    Desc string     `json:"desc"`
    Sub  []*sub     `json:"sub"`
}

full example (Thanks to chmike for doing most of the heavy lifting/formatting for that example)完整示例(感谢 chmike 为该示例完成了大部分繁重的工作/格式化)

If you want to do some more digging into golang and pointers there are plenty of resources online such as the official documentation , which has some information spread around, or geeksforgeeks which is a bit more focused with examples.如果你想深入研究 golang 和指针,可以在网上找到大量资源,例如官方文档,其中包含一些信息,或者更侧重于示例的geeksforgeeks Just be aware of golang's automatic dereferencing请注意golang 的自动取消引用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM