使用 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]string
和 map[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))
}
我想创建一个输出 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]string
和 map[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))
}