很新,很抱歉,如果这个问题听起来很明显。
在读取json文件时,我想使用反射来识别对象的类型。
用例(请参见下面的代码)如下:我有两个结构BoyGift和GirlGift,它们包含不同的字段。我还有一个布尔指标IsBoy,如果礼物的接收者是男孩,则为true,否则为false。
封装此行为的类型是Gift类型:
//Gift type
type Gift struct {
IsBoy bool `json:"isBoy"`
Payload ??? `json:"payload"`
}
保存数据。如何定义该类型以便json解组器动态转换为正确的类型?在这种情况下,“ json模式”定义了Gift应该是BoyGift或GirlGift。是否可以通过反射来做到这一点?怎么样?
如果知道布尔信息,那么两次解组将是很好的选择
package main
import (
"encoding/json"
"fmt"
)
//BoyGift type
type BoyGift struct {
Cars uint32 `json:"cars"`
Balls uint32 `json:"balls"`
}
//GirlGift type
type GirlGift struct {
Dolls uint32 `json:"dolls"`
Lego uint32 `json:"lego"`
}
//Gift type
type Gift struct {
IsBoy bool `json:"isBoy"`
Payload GirlGift `json:"payload"`
}
func main() {
b := []byte(`{
"isBoy": true,
"payload": {
"cars": 1,
"balls": 2
}
}`)
var g Gift
err := json.Unmarshal(b, &g)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(g)
}
答案 0 :(得分:1)
您应该使用json.RawMessage
动态解组数据。
您可以将Gift's Payliad定义为json.RawMessage
,然后延迟取消编组,直到您知道IsBoy
的值为止。在下面,您可以找到有关此操作的基本示例。
package main
import (
"encoding/json"
"fmt"
)
//BoyGift type
type BoyGift struct {
Cars uint32 `json:"cars"`
Balls uint32 `json:"balls"`
}
//GirlGift type
type GirlGift struct {
Dolls uint32 `json:"dolls"`
Lego uint32 `json:"lego"`
}
//Gift type
type Gift struct {
IsBoy bool `json:"isBoy"`
Payload json.RawMessage `json:"payload"`
}
func main() {
b1 := []byte(`{
"isBoy": true,
"payload": {
"cars": 1,
"balls": 2
}
}`)
b2 := []byte(`{
"isBoy": false,
"payload": {
"dolls": 3,
"lego": 4
}
}`)
for _, b := range [][]byte{b1, b2} {
var g Gift
err := json.Unmarshal(b, &g)
if err != nil {
fmt.Println(err)
return
}
if g.IsBoy {
var boyGift BoyGift
err := json.Unmarshal(g.Payload, &boyGift)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(boyGift)
} else {
var girlGift GirlGift
err := json.Unmarshal(g.Payload, &girlGift)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(girlGift)
}
}
}
如果您想将Payload
用作interface{}
(可以是BoyGift
或GirlGift
),则可以创建用于解组的其他辅助结构。在Go Playground中查看扩展示例:https://play.golang.org/p/q1Hn45bgjsc