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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28254102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:43:40  来源:igfitidea点击:

How to unmarshal JSON into interface{} in Go?

jsongo

提问by Shanicky_C

I'm a newbie in Go and now I have a problem. I have a type called Message, it is a struct like this:

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

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

I also have a type called CreateMessage like this:

我还有一个叫做 CreateMessage 的类型,如下所示:

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

And I have a JSON string like {"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}}.

我有一个像{"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}}.

When I use json.Unmarshalto decode that into a Message variable, the answer is {Cmd:create Data:map[conf:map[a:1] info:map[b:2]]}.

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

So could I decode the JSON into a Message struct and change its Data's interface{} to type CreateMessage according to the Cmd?

那么我可以将 JSON 解码为 Message 结构并根据 Cmd 更改其数据接口{}以键入 CreateMessage 吗?

I tried to convert Data directly into type CreateMessage but the complier told me that Data is a map[sting]interface{} type.

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

回答by Cerise Limón

Define a struct type for the fixed part of the message with a json.RawMessagefield to capture the variant part of the message. Define struct types for each of the variant types and decode to them based on the the command.

使用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")
    }
}

playground example

游乐场示例