Как сделать карту с пустыми значениями структуры в go - PullRequest
0 голосов
/ 21 января 2020

Как сделать go карту такой структуры:


{
    "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",
                }
            ] 
        },
    ]
}

Я пытался сделать это, но не получаю. Как создать пустую структуру / массив и как создать структуру в структуре?


    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", ??? },
        },
    }

Ответы [ 3 ]

3 голосов
/ 21 января 2020

В оригинале 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"`
}

К вашему сведению, ниже приведена очищенная / исправленная синтаксисом версия вашего 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"
                }
            ] 
        }
    ]
}
1 голос
/ 21 января 2020

На основе примера JSON, появляется , что вы пытаетесь создать рекурсивную структуру JSON. Рекурсивные JSON (и рекурсивные структуры) очень полезны, но вы должны убедиться, что вы правильно их построили, иначе вы можете столкнуться с ситуациями, когда структура не может быть создана в памяти.

Давайте рассмотрим простой пример:

type example struct {
    itemOne int64
    subElement example
}

Когда программа начинает создавать структуру в памяти, она должна выяснить, насколько она должна быть большой. Этот процесс выглядит следующим образом:

  1. выяснить, насколько велик элемент itemOne.
    • Добавьте 8 байтов в пространство выделения. (Итого: 8)
  2. выяснить, насколько велик подэлемент.
    1. выяснить, насколько велика subElement-itemOne
      • Добавить 8 байтов в пространство выделения. (Всего: 16)
    2. выяснить, насколько велик subElement-subElement
      1. et c.

Этот процесс будет продолжаться вечно до тех пор, пока 1: не произойдет переполнение стека в программе, вычисляющей объем памяти, или 2: общий объем требуемой памяти слишком велик для программы.

In в случае Go эта ситуация фактически имеет встроенное обнаружение, поэтому второй шаг фактически никогда не выполняется. Например, возвращает ./prog.go:7:6: invalid recursive type example.

Решением этой проблемы является создание структуры, в которой калькулятор знает точный размер всего, что он должен добавить в структуру. Для этого мы используем тот факт, что все структуры имеют общий размер указателя на их расположение в памяти.

type example struct {
    itemOne int64
    subElement *example
}

Добавление этой единственной звездочки делает рекурсивный процесс конечным.

  1. выясните, каков размер элемента itemOne.
    • Добавьте 8 байтов в пространство выделения. (Всего: 8)
  2. выяснить, насколько велика подэлемент указатель .
    • Добавление 8 байтов в пространство выделения (всего 16)
  3. Очистка и распределение 16 байтов.

Значения затем устанавливаются по умолчанию. Целые числа установлены в ноль и указывают на нулевое значение (также ноль). Передача одного из них в json unmarshal создаст именно ту структуру, которую вы ищете.

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

полный пример (Спасибо chmike за большую часть тяжелой работы / форматирование для этого примера)

Если вы хотите еще немного покопаться в golang и указателях, в Интернете есть множество ресурсов, таких как официальная документация , которая содержит некоторую информацию, или geeksforgeeks , который немного более сфокусирован на примерах. Просто помните о golang автоматах c разыменование

1 голос
/ 21 января 2020

Вы можете использовать следующее определение типа структуры, которое будет работать. Он избегает interface{}, который не удобно использовать для доступа к данным. Измените имена классов по своему вкусу.

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)
    }
}

Выходы

done: {[{My name aaaa []} {Loc bbbb [{xxxxx aaaa} {yyyyy aaaa}]}] [{My name b cccc []} {tyty ffff [{rrrrrr descrition}]}]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...