英文:
Unmarshal a JSON array of heterogeneous structs
问题
我想要反序列化一个包含某个接口Entity
数组的对象:
type Result struct {
Foo int;
Bar []Entity;
};
Entity
是由多个结构体类型实现的接口。JSON数据通过每个实体中的"type"字段来标识结构体类型。例如:
{"type":"t1","field1":1}
{"type":"t2","field2":2,"field3":3}
我应该如何反序列化Result
类型,以正确填充数组?从我所看到的,我需要:
- 在
Result
上实现UnmarshalJSON
。 - 将
Bar
解析为[]*json.RawMessage
。 - 将每个原始消息解析为
map[string]interface{}
。 - 检查原始消息中的"type"字段。
- 创建适当类型的结构体。
- 再次解析原始消息,这次解析到刚创建的结构体中。
这听起来非常繁琐和无聊。有没有更好的方法来做这个?或者我是在反过来做,有没有更规范的方法来处理异构对象数组?
英文:
I want to deserialise an object that includes an array of a some interface Entity
:
type Result struct {
Foo int;
Bar []Entity;
};
Entity
is an interface that is implemented by a number of struct types. JSON data identifies the struct type with a "type" field in each entity. E.g.
{"type":"t1","field1":1}
{"type":"t2","field2":2,"field3":3}
How would I go about deserialising the Result
type in such a way that it correctly populates the array. From what I can see, I have to:
- Implement
UnmarshalJSON
onResult
. - Parse
Bar
as a[]*json.RawMessage
. - Parse each raw message as
map[string]interface{}
. - Check "type" field in the raw message.
- Create a struct of appropriate type.
- Parse the raw message again, this time into the just created struct.
This all sounds very tedious and boring. Is there a better way to do this? Or am I doing it backwards, and there is a more canonical method to handle an array of heterogeneous objects?
答案1
得分: 5
我认为你的过程可能比必要的要复杂一些,可以参考http://play.golang.org/p/0gahcMpuQc。一个单独的map[string]interface{}可以处理很多事情。
或者,你可以创建一个类型,如下所示:
struct EntityUnion {
Type string
// 来自t1的字段
// 来自t2的字段
// ...
}
将其解组为该类型;它将设置Type字符串并填充所有可以从JSON数据中获取的字段。然后,你只需要一个小函数将字段复制到特定的类型中。
英文:
I think your process is probably a bit more complicated than it has to be, see http://play.golang.org/p/0gahcMpuQc. A single map[string]interface{} will handle a lot of that for you.
Alternatively, you could make a type like
struct EntityUnion {
Type string
// Fields from t1
// Fields from t2
// ...
}
Unmarshal into that; it will set the Type string and fill in all the fields it can get from the JSON data. Then you just need a small function to copy the fields to the specific type.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论