Kay*_*lly 4 json go unmarshalling
我正在研究golang中基于JSON的通用消息传递协议.我想要做的是BaseMessage拥有一般信息,如Type,timestamp等等.但同时我希望能够为某些类型的数据定义更具体的消息结构.
例如:
type Message struct {
Type string `json:type`
Timestamp string `json:timestamp`
}
type EventMessage struct {
Message
EventType string
EventCreator string
EventData interface{}
}
Run Code Online (Sandbox Code Playgroud)
我有一组处理程序,并确定哪个处理程序应该处理消息我首先将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)
Run Code Online (Sandbox Code Playgroud)
我试图使用一个,interface{}但然后JSON解码器只是创建一个地图,然后我不能断言任何类型.我已经找到了可行的解决方法,但它非常难看,可能效率不高,而且很可能容易出错.我想保持简单明了的事情,这样就可以轻松维护这些代码.
是否有一种在Golang中处理通用JSON对象的方法,以便解码的JSON可以是许多结构格式之一?
我也想过在Data interface{}主Message结构中有更多特定信息的想法,但后来我遇到了无法在接口上断言任何类型的相同问题.必须有一种更好的方法来处理我刚才缺少的JSON格式.
Cer*_*món 16
处理此问题的一种方法是使用json.RawMessage字段为消息的固定部分定义结构,以捕获消息的变体部分.将json.RawMessage解码为特定于变体的类型:
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")
}
Run Code Online (Sandbox Code Playgroud)