2 回答

TA贡献1856条经验 获得超5个赞
您可以做的一件事是使用json.RawMessage类型和自定义包装器类型。然后,在收到消息后,您可以进行切换(或使用构造函数映射)来获取正确的结构。
例如(省略错误检查):
package main
import (
"encoding/json"
"fmt"
)
type Message struct {
Type string
Data json.RawMessage
}
func (m Message) Struct() interface{} {
unmarshaller, found := unmarshallers[m.Type]
if !found {
return nil
}
return unmarshaller([]byte(m.Data))
}
type Foo struct {
ID int
}
var unmarshallers = map[string]func([]byte) interface{}{
"foo": func(raw []byte) interface{} {
var f Foo
json.Unmarshal(raw, &f)
return f
},
}
func main() {
var body = []byte(`{"Type":"foo","Data":{"ID":1}}`)
var msg Message
json.Unmarshal(body, &msg)
switch s := msg.Struct().(type) {
case Foo:
fmt.Println(s)
}
}
请参阅此游乐场示例以获取现场演示http://play.golang.org/p/7FmQqnWPaE

TA贡献1833条经验 获得超4个赞
根据您的评论,这可能是一个解决方案:
type Packet {
Type string
Data []byte
}
编码功能:
func packageEncode(i interface{}) ([]byte, error) {
b, err := json.Marshal(i)
if err != nil {
return nil, err
}
p := &Package{Data: b}
switch t.(type) {
case a:
p.Type = "a"
case b:
p.Type = "b"
case c:
p.Type = "c"
}
return json.Marshal(p)
}
然后,当收到消息并解码时:
p := &Package{}
err = json.Unmarshal(recievedBytes[0:nrOfBytes], p)
...
if p.Type == "a" {
msg := &a{}
err = json.Unmarshal(p.Data, msg)
}
if p.Type == "b" {
...
}
- 2 回答
- 0 关注
- 188 浏览
添加回答
举报