使用 struct 使用 key:value 作为标记名称创建 JSON 输出时出现问题

Issue in Creating JSON output with key:value as tag names using struct

我想创建一个输出 JSON,如下所示,

{
   "Name": "John Smith",
   "City": "London",
   "Contact": [
     { "key": "StreetName", "value": "SomeName" },
     { "key": "PostalCode", "value": "SomeValue" }
   ],
}

我正在尝试使用以下代码实现此目的,

package main

import (
        "encoding/json"
        "fmt"
        "log"
)

type Person struct {
   Name, City string
   Contact ContactStruct   
}

type ContactStruct struct {
   Street, PostalCode map[string]string
}

func main() {
  StreetData := make(map[string]string)
  StreetData["key"] = "StreetName"
  StreetData["value"] = "ABC Street"

  PostalCodeData := make(map[string]string)
  PostalCodeData["key"] = "PostalCode"
  PostalCodeData["value"] = "12345"

  jsonData := Person{
    Name: "John Smith",
    City: "London",
    Contact: ContactStruct{
       StreetData,
       PostalCodeData,
    },
  }

  finalJsonData, err := json.MarshalIndent(jsonData, " ", "   ")
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println(string(finalJsonData))
}

下面是使用上述代码生成的输出,

 {
    "Name": "John Smith",
    "City": "London",
    "Contact": {
       "Street": {
          "key": "StreetName",
          "value": "ABC Street"
       },
       "PostalCode": {
          "key": "PostalCode",
          "value": "12345"
       }
    }
 }

问题:如我们所见,正在使用标签名称 "Street"PostalCode 创建输出,因为我们正在使用结构值创建 JSON。

我尝试探索在 Person struct 中使用 map[string]stringmap[string]interface{} 的各种选项。但它不起作用。

根据问题开头显示的我的要求,是否有任何更好的实现可用于获得 JSON 输出。

在此先感谢您的帮助。我最近开始用golang开发。

运行 来源可在此处获得:https://play.golang.org/p/eIxDyWXfZ1C

也许你想要这样


type Person struct {
    Name, City string
    Contact    []ContactStruct
}

type ContactStruct struct {
    Key   string
    Value string
}

func main() {

    StreetData := ContactStruct{Key: "StreetName", Value: "ABC Street"}
    PostalCodeData := ContactStruct{Key: "PostalCode", Value: "12345"}
    jsonData := Person{
        Name:    "John Smith",
        City:    "London",
        Contact: []ContactStruct{StreetData, PostalCodeData},
    }
    finalJsonData, err := json.MarshalIndent(jsonData, " ", "   ")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(finalJsonData))
}

您的结构有点奇怪,但这是解决方案: https://play.golang.org/p/CCVuiGd5phq

快速提示:https://mholt.github.io/json-to-go/ 当您需要 json 的结构时使用此页面。

您可能想为 ContactStruct 使用自定义 JSON 封送拆收器。这允许继续使用干净的 Go 数据类型,但仍然实现预期与外界通信的特定序列化。

Go playground 上查看和 运行:

package main

import (
        "encoding/json"
        "fmt"
        "log"
)

type Person struct {
   Name, City string
   Contact ContactStruct   
}

type ContactStruct struct {
   Street, PostalCode string
}

func appendKV(buf []byte, key string, value string) ([]byte) {
    buf = append(buf, []byte(`{"key":`)...)
    b, _ := json.Marshal(key)
    buf = append(buf, b...)
    buf = append(buf, []byte(`,"value":`)...)
    b, _ = json.Marshal(value)
    buf = append(buf, b...)
    buf = append(buf, '}')
    return buf
}

func (cs ContactStruct) MarshalJSON() ([]byte, error) {
    buf := []byte{'['}
    buf = appendKV(buf, "StreetName", cs.Street)
    buf = append(buf, ',')
    buf = appendKV(buf, "PostalCode", cs.PostalCode)
    buf = append(buf, ']')
    return buf, nil
}


func main() {
  jsonData := Person{
    Name: "John Smith",
    City: "London",
    Contact: ContactStruct{
       Street: "ABC Street",
       PostalCode: "12345",
    },
  }

  finalJsonData, err := json.MarshalIndent(jsonData, " ", "   ")
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println(string(finalJsonData))
}