【问题标题】:JSON: Nesting a populated struct into a new structJSON:将填充的结构嵌套到新结构中
【发布时间】:2017-04-02 16:12:34
【问题描述】:

我有一个这样的结构:

type my_struct struct {
  First  string `json:"first"`
  Second string `json:"second"`
  Number int    `json:"number"`
}

当我将其编组为 JSON 时,它会输出您所期望的非常简单的 JSON:

var output_json []byte
output_json, _ = json.Marshal(output)
fmt.Println(string(output_json))

结果:

{"first":"my_string","second":"another_string","number":2}

到目前为止一切顺利!

在将该结构编组为 JSON 之前,我想做的是将其嵌套在另一个结构中。结果输出将是如下所示的 JSON:

{
  "fields": {
    "first": "my_string",
    "number": 2,
    "second": "another_string"
  },
  "meta": "data"
}

我该怎么做?

【问题讨论】:

    标签: json go struct


    【解决方案1】:

    我认为您可以静态声明要使用的另一个结构:

    type WrappedOutput struct {
      fields my_struct
      meta string
    }
    

    然后你可以在编组之前嵌入你的结构

    o := WrappedOutput{fields: output}

    全新,所以不确定这是否是最简单的方法

    【讨论】:

      【解决方案2】:

      这样做的干净方法是声明 2 个结构(我在下面全局完成了它)并将 My_struct 嵌套在更高级别的结构中。

      然后你可以在 Mashalling 之前初始化更高级别的结构:

      package main
      
      import (
          "encoding/json"
          "fmt"
      )
      
      type My_struct struct {
          First  string `json:"first"`
          Second string `json:"second"`
          Number int    `json:"number"`
      }
      
      type Big_struct struct {
          Fields My_struct
          Meta   string
      }
      
      func main() {
      
          output := Big_struct{
              Fields: My_struct{
                  First:  "my_string",
                  Second: "another_string",
                  Number: 2,
              },
              Meta: "data",
          }
      
          output_json, err := json.Marshal(output)
          if err != nil {
              fmt.Println(err)
          }
      
          fmt.Println(string(output_json))
      
      }
      

      如果您不想要Big_struct,您可以根据需要在代码中声明一个匿名结构并将My_struct 嵌套在其中:

      package main
      
      import (
              "encoding/json"
              "fmt"
      )
      
      type My_struct struct {
              First  string `json:"first"`
              Second string `json: "second"`
              Number int    `json:"number"`
      }
      
      func main() {
      
              output := struct {
                      Fields My_struct
                      Meta   string
              }{  
                      Fields: My_struct{
                              First:  "my_string",
                              Second: "another_string",
                              Number: 2,
                      },  
                      Meta: "data",
              }   
      
              output_json, err := json.Marshal(output)
              if err != nil {
                      fmt.Println(err)
              }   
      
              fmt.Println(string(output_json))
      
      }
      

      【讨论】:

      • 我遇到的问题是我并不总是需要 big_struct,它是有条件的。有没有办法不这样做?
      • @Frap 您无法使用您未声明的新字段专门初始化 My_struct。 Go 没有你在 Python 中看到的相同类型的面向对象继承。但是,您可以声明一个有条件的匿名结构并将My_struct 嵌套在其中。我用第二个例子编辑了我的答案。
      【解决方案3】:

      如果你不想使用新的结构,你可以这样做:

      data := my_struct{First: "first", Second: "2", Number: 123}
      result, _ := json.Marshal(&map[string]interface{}{"fields":data,"meta":"data"})
      fmt.Println(string(result))
      

      它不干净,但它可以工作。

      【讨论】:

        猜你喜欢
        • 2014-10-12
        • 1970-01-01
        • 2015-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-21
        • 1970-01-01
        相关资源
        最近更新 更多