用嵌套数组编组 JSON?

分享于2022年07月17日 go json 问答
【问题标题】:用嵌套数组编组 JSON?(Marshaling JSON with nested array?)
【发布时间】:2022-01-16 12:03:27
【问题描述】:

我想像这样创建 JSON:

{
  "name": "val1",
  "version": "val2",
  "type": "val3",
  "settings": [
    "setting1,
    "setting2",
    "setting3",
    [
      "option1",
      "option2"
    ] 
  ]
}

但我不知道如何在 settings 中创建嵌套数组:

package main

import (
        "encoding/json"
        "fmt"
)

type Config struct {
        Name     string   `json:"name"`
        Version  string   `json:"version"`
        Type     string   `json:"type"`
        Settings []string `json:"settings"`
}

func main() {
        settings := []string{"setting1", "setting2", "setting3"}
        options := []string{"option1", "option2"}
        setopts := append(settings, options...)

        c := &Config{"val1", "val2", "val3", setopts}

        j, err := json.Marshal(c)
        if err != nil {
                panic(err)
        }

        fmt.Println(string(j))
}

通过 jq 管道输出以提高可读性:

$ ./main | jq
{
  "name": "val1",
  "version": "val2",
  "type": "val3",
  "settings": [
    "setting1",
    "setting2",
    "setting3",
    "option1",
    "option2"
  ]
}

结果是 option1 option2 settings 数组中的值,但它们应该位于 settings 的嵌套数组中。此外,编组时选项可能并不总是存在,在这种情况下不应创建嵌套数组。

我怎样才能做到这一点?


【解决方案1】:

您在此处显示的输出:

    "setting1",
    "setting2",
    "setting3",
    [
      "option1",
      "option2"
    ]

可以描述为 JSON 字符串 字符串数组。

您可以使用 []interface{} 对其进行建模,并将字符串或切片附加到其上:

type Config struct {
        Name     string        `json:"name"`
        Version  string        `json:"version"`
        Type     string        `json:"type"`
        Settings []interface{} `json:"settings"`
}

func main() {
        settings := []interface{}{
              "setting1", 
              "setting2", 
              "setting3",
              []string{"option1", "option2"},
        }

        c := &Config{"val1", "val2", "val3", settings}

        j, err := json.Marshal(c)
        if err != nil {
                panic(err)
        }

        fmt.Println(string(j))
}

游乐场: https://go.dev/play/p/8LPAVBPmd8w

  • 仅供参考:您可以使用“MarshalIndent()”而不是“Marshal()”来输出缩进的 json。