json - 如何在 Go 中将 JSON 解码为 interface{}?

标签 json 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 结构并根据 Cmd 更改其 Data 的接口(interface){} 以键入 CreateMessage 吗?

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

最佳答案

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

关于json - 如何在 Go 中将 JSON 解码为 interface{}?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28254102/

相关文章:

iphone - 从 JSON 在 Devise 中创建用户

javascript - 导入 JSON 并转换为数组

javascript - 获取 json 数据时 jquery 有问题

ios - Restkit如何映射任意json(keys可能会超时改变)到NSDictionary

go - 如何在 Visual Studio Code 中编辑默认的 go 测试超时?

go - 从内部函数引用外部函数中的值安全吗?

json - 为什么 glTF 模式要这样定义枚举?

go - Golang 的 ... 语法真的只是可变参数吗?

amazon-web-services - AWS X-Ray GoLang Lambda 到 lambda 跟踪并显示在服务 map 中

运行时错误 : “assignment to entry in nil map”