一尘不染

如何在Go中将JSON解组到interface {}中?

go

我是Go的新手,现在遇到了问题。我有一个称为Message的类型,它是这样的结构:

type Message struct {
    Cmd string `json:"cmd"`
    Data interface{} `json:"data"`
}

我也有一个名为CreateMessage的类型,如下所示:

type CreateMessage struct {
    Conf map[string]int `json:"conf"`
    Info map[string]int `json:"info"`
}

我有一个像的JSON字符串{"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}}

当我用来json.Unmarshal将其解码为Message变量时,答案是{Cmd:create Data:map[conf:map[a:1] info:map[b:2]]}

因此,我可以将JSON解码为Message结构并更改其Data的接口{}以根据Cmd键入CreateMessage吗?

我试图将Data直接转换为CreateMessage类型,但是编译器告诉我Data是map [sting] interface {}类型。


阅读 291

收藏
2020-07-02

共1个答案

一尘不染

使用json.RawMessage字段为消息的固定部分定义结构类型,以捕获消息的变体部分。为每个变量类型定义结构类型,并根据命令对其进行解码。

type Message struct {
  Cmd string `json:"cmd"`
  Data      json.RawMessage
}

type CreateMessage struct {
    Conf map[string]int `json:"conf"`
    Info map[string]int `json:"info"`
}

func main() {
    var m Message
    if err := json.Unmarshal(data, &m); err != nil {
        log.Fatal(err)
    }
    switch m.Cmd {
    case "create":
        var cm CreateMessage
        if err := json.Unmarshal([]byte(m.Data), &cm); err != nil {
            log.Fatal(err)
        }
        fmt.Println(m.Cmd, cm.Conf, cm.Info)
    default:
        log.Fatal("bad command")
    }
}

游乐场的例子

2020-07-02