我有一个JSON对象,其详细信息可以包含不同类型的JSON对象,其余JSON保持不变,在这种情况下,我如何在Golang中使用单个结构来处理两种类型的JSON
JSON 1:
{
"field1":"",
"field2":"",
"field3":"",
"field4":"",
"field5":"",
"field6":"",
"field7":"",
"details":{
"detail1":"",
"detail2":[
{
"arr1":"",
"arr2":{
"id":"",
"name":""
},
"list":[
{
"id":"",
"version":1,
"name":""
}
]
}
]
},
"user":{
"id":"",
"name":""
}
}
JSON 2:
{
"field1":"",
"field2":"",
"field3":"",
"field4":"",
"field5":"",
"field6":"",
"field7":"",
"details":{
"anotherdetail1":"",
"anotherdetail2":[
{
"arr7":"",
"arr8":{
"id":"",
"name":""
},
"arr10":{
}
}
]
},
"user":{
"id":"",
"name":""
}
}
我的目标是对这两个JSON对象使用单个结构。在Java之类的语言中,我将创建一个父类,该类以通用的方式类似于细节,并具有2个子类以类似于变化的细节类型,并且在运行时,我将创建一个子类型的对象并将其分配给Parent。我不确定Go中该如何完成。
答案 0 :(得分:3)
除非可以使用字符串接口映射,否则我不确定您是否可以使用单个结构,但是可以通过将 details 设置为json.RawMessage
类型来防止对其进行解码他构造。然后,您可以通过尝试将未知类型的json数据解码为一种类型来对其进行解码,如果返回错误,则尝试使用下一种类型。
这是一些代码,应该可以使您更好地了解我在说什么。
https://play.golang.org/p/06owmiJXNaO
package main
import (
"encoding/json"
"fmt"
)
const json1 = `{"name": "foo", "details":[1, 2, 3]}`
const json2 = `{"name": "foo", "details":{"a": [1, 2, 3]}}`
type data struct {
Name string `json:"name"`
Details json.RawMessage `json:"details"`
}
type detailsone []int
type detailstwo struct {
A []int `json:"a"`
}
func main() {
var d1, d2 data
json.Unmarshal([]byte(json1), &d1)
json.Unmarshal([]byte(json2), &d2)
fmt.Printf("%+v\n", d1)
fmt.Printf("%+v\n", d2)
var err error
var b1 detailsone
var b2 detailstwo
// json1
err = json.Unmarshal([]byte(d1.Details), &b1)
if err == nil {
fmt.Printf("d1 is an []int: %+v\n", b1)
}
err = json.Unmarshal([]byte(d1.Details), &b2)
if err == nil {
fmt.Printf("d1 is an detailstwo struct: %+v\n", b2)
}
// json2
err = json.Unmarshal([]byte(d2.Details), &b1)
if err == nil {
fmt.Printf("d2 is an []int: %+v\n", b1)
}
err = json.Unmarshal([]byte(d2.Details), &b2)
if err == nil {
fmt.Printf("d2 is an detailstwo struct: %+v\n", b2)
}
}
答案 1 :(得分:0)
type Base struct {
Data map[string]interface{}
Details struct {
*D1
*D2
} `json:"details"
}
type D1 struct {
Detail1 string
Detail2 string
}
type D2 struct {
AnotherDetail1 string
AnotherDetail2 string
}
您可以通过将填充的结构与nil
进行比较来找到填充的结构