[英]How to Unmarshal stream of different types
I have a stream of objects of different but known, types and I'm struggling to figure out how to unmarshal the JSON encoded stream into Go structs. I have a stream of objects of different but known, types and I'm struggling to figure out how to unmarshal the JSON encoded stream into Go structs.
Here is a sample slice for illustration purpose这是用于说明目的的示例切片
[
{
"uid": "xyz1",
"type": "person",
"name": "John",
"surname": "King"
},
{
"uid": "xyz2",
"type": "thing",
"car": "benz",
"shoes": "nike"
},
{
"uid": "xyz3",
"type": "person",
"name": "Mary",
"surname": "Queen"
}
]
As you can see there is a type
field that informs the receiver about what is the type of the object.如您所见,有一个type
字段通知接收器 object 的类型是什么。
Data maps into the following Go types in the stream which "share" UID
and Type
fields:数据映射到“共享” UID
和Type
字段的 stream 中的以下 Go 类型:
type Person struct {
UID string
Type string
Name string
Surname string
}
type Thing struct {
UID string
Type string
Car string
Shoes string
}
I found a similar question here , though unanswered, it's a bit different from what I need to deal with.我在这里发现了一个类似的问题,虽然没有得到解答,但与我需要处理的问题有点不同。 Instead of being guaranteed a transaction
keyspace as I've no guarantee what the payload should look like besides the type
and uid
fields.除了type
和uid
字段之外,我无法保证有效负载应该是什么样子,而不是保证transaction
密钥空间。
Is there some way to this other than drowning deeply in reflect
package?除了沉浸在reflect
package 之外,还有其他方法吗?
Unmarshal to a slice of raw messages :将原始消息解组:
var elems []json.RawMessage
err := json.Unmarshal(data, &elems)
if err != nil {
log.Fatal(err)
}
For each element in the slice, unmarshal once to find the type and a second time to the specific type:对于切片中的每个元素,解组一次以查找类型,第二次解组为特定类型:
for _, elem := range elems {
// Pick out the type field.
var t struct {
Type string
}
err := json.Unmarshal(elem, &t)
if err != nil {
log.Fatal(err)
}
// Decode to specific type based on value of the type field.
switch t.Type {
case "person":
var p Person
err := json.Unmarshal(elem, &p)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", p)
case "thing":
var t Thing
err := json.Unmarshal(elem, &t)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", t)
default:
fmt.Printf("unknown type %s\n", t.Type)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.