Golang JSON Сериализация / Десериализация - PullRequest
0 голосов
/ 24 марта 2019

У меня есть следующая структура:

type Node struct {
    Name     string
    Children []*Node
    Values   []string
}

У меня также есть набор файлов json, описывающих мои деревья, таких как:

{
  "something": {
    "someblah": [
      "fluf",
      "glah"
    ],
    "someother": {
      "someotter": [
        "blib",
        "fnar"
      ]
    }
  }
}

Как я могу десериализовать эти файлы вstructs?

Все примеры, которые я нашел, требуют другой структуры с именованными парами ключ / значение.

Для этого структура является ключевой:

  • ключом является имя структуры
  • содержимое карты является дочерним
  • содержимое списказначения

Я не могу понять, как отобразить эту логику в сериализатор golang json.

1 Ответ

2 голосов
/ 24 марта 2019

Самый простой подход - это декодировать на карту [string] interface {} и преобразовать ее в желаемую структуру:

var m map[string]interface{}
err := json.Unmarshal(data, &m)
if err != nil {
    // handle error
}
node := convert(m, "")

...

func convert(name string, m map[string]interface{}) *Node {
    n := Node{Name: name}
    for k, v := range m {
        switch v := v.(type) {
        case []interface{}:
            nn := Node{Name: k}
            for _, e := range v {
                s, ok := e.(string)
                if !ok {
                    panic(fmt.Sprintf("expected string, got %T", e))
                }
                nn.Values = append(nn.Values, s)
            }
            n.Children = append(n.Children, &nn)
        case map[string]interface{}:
            n.Children = append(n.Children, convert(k, v))
        default:
            panic("unexpected type")
        }
    }
    return &n
}

Функция convert вызывает панику, когда встречает значение неожиданного типа.В зависимости от требований вашего приложения вы можете игнорировать эти значения или возвращать ошибку.

Запустите его на игровой площадке .

...