将通用JSON对象解码为多种格式之一 [英] Decoding generic JSON objects to one of many formats
问题描述
我正在Go中基于通用JSON的消息传递协议上工作.我想做的是有一个BaseMessage
,它具有诸如Type
,timestamp
等一般信息.但是同时,我希望能够为某些类型的数据定义更具体的消息结构. /p>
例如:
type Message struct {
Type string `json:type`
Timestamp string `json:timestamp`
}
type EventMessage struct {
Message
EventType string
EventCreator string
EventData interface{}
}
我有一组处理程序,并确定哪个处理程序应处理该消息,我首先将JSON解码为常规的Message
类型,以检查Type
字段.对于此示例,我将获得与事件"消息类型关联的处理程序.
然后我想在结构上声明EventMessage
类型时遇到问题.
下面的代码很粗糙,但希望它能显示我对如何处理消息的一般想法.
type Handler func(msg Message) Message
handlers := make(map[string]Handler)
var msg Message
decoder.Decode(&msg)
handler := handlers[msg.Type]
handler(msg)
我尝试使用interface{}
,但是JSON解码器仅创建了一个映射,然后我无法断言这两种类型.我已经找到了使之成为可能的变通办法,但是它非常丑陋,可能效率不高,而且很容易出错.我想让事情简单明了,以便可以轻松维护此代码.
在Go中是否有一种处理通用JSON对象的方法,以便解码后的JSON可以是许多结构格式之一?
我也曾想过在主Message
结构中的Data interface{}
中包含更多特定信息,但是随后遇到了一个同样的问题,即无法在接口上声明任何类型.必须有一种更好的方式来处理我刚丢失的JSON格式.
一种解决方法是使用 I am working on a general JSON based message passing protocol in Go. What I would like to do is have a For example: I have a set of handlers and to determine which handler should process the message I decode the JSON to the general I run into problems when I then want to assert the The following code is very rough, but hopefully it displays my general idea of how I am trying to handle the messages. I have tried to use an Is there a method of handling generic JSON objects in Go so that the decoded JSON could be one of many struct formats? I have also played with the idea of having more specific info in a One way to handle this is to define a struct for the fixed part of the message with a json.RawMessage field to capture the variant part of the message. Decode the json.RawMessage to a type specific to the variant: 这篇关于将通用JSON对象解码为多种格式之一的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!BaseMessage
that has general information like Type
, timestamp
, etc. But at the same time I want to be able to define more specific message structures for certain types of data.type Message struct {
Type string `json:type`
Timestamp string `json:timestamp`
}
type EventMessage struct {
Message
EventType string
EventCreator string
EventData interface{}
}
Message
type first to check the Type
field. For this example I would get the handler associated with an "Event" message type. EventMessage
type onto the structure.type Handler func(msg Message) Message
handlers := make(map[string]Handler)
var msg Message
decoder.Decode(&msg)
handler := handlers[msg.Type]
handler(msg)
interface{}
but then the JSON decoder just creates a map which I then cant assert either type on. I have figured out workarounds that make it possible, but its very ugly, probably not efficient, and most likely error prone. I would like to keep things simple and straightforward so this code can be easily maintained.Data interface{}
in the main Message
struct, but then I run into the same problem of not being able to assert any types onto the interface. There has to be a better way to handle JSON formats that I am just missing.type Message struct {
Type string `json:type`
Timestamp string `json:timestamp`
Data json.RawMessage
}
type Event struct {
Type string `json:type`
Creator string `json:creator`
}
var m Message
if err := json.Unmarshal(data, &m); err != nil {
log.Fatal(err)
}
switch m.Type {
case "event":
var e Event
if err := json.Unmarshal([]byte(m.Data), &e); err != nil {
log.Fatal(err)
}
fmt.Println(m.Type, e.Type, e.Creator)
default:
log.Fatal("bad message type")
}