解组异构结构的JSON数组

时间:2022-12-19 00:57:13

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.

实体是由许多结构类型实现的接口。 JSON数据标识每个实体中具有“类型”字段的结构类型。例如。

{"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:

我将如何以正确填充数组的方式对结果类型进行反序列化。从我所看到的,我必须:

  1. Implement UnmarshalJSON on Result.
  2. 在Result上实现UnmarshalJSON。
  3. Parse Bar as a []*json.RawMessage.
  4. 将Bar解析为[] * json.RawMessage。
  5. Parse each raw message as map[string]interface{}.
  6. 将每条原始消息解析为map [string] interface {}。
  7. Check "type" field in the raw message.
  8. 检查原始邮件中的“类型”字段。
  9. Create a struct of appropriate type.
  10. 创建适当类型的结构。
  11. Parse the raw message again, this time into the just created struct.
  12. 再次解析原始消息,这次是刚创建的结构。

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 个解决方案

#1


5  

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.

我认为你的过程可能比它有点复杂,请参阅http://play.golang.org/p/0gahcMpuQc。单个map [string] interface {}将为您处理很多这样的事情。

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.

解散;它将设置Type字符串并填写它可以从JSON数据中获取的所有字段。然后,您只需要一个小函数将字段复制到特定类型。

#1


5  

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.

我认为你的过程可能比它有点复杂,请参阅http://play.golang.org/p/0gahcMpuQc。单个map [string] interface {}将为您处理很多这样的事情。

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.

解散;它将设置Type字符串并填写它可以从JSON数据中获取的所有字段。然后,您只需要一个小函数将字段复制到特定类型。