首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Go中解组JSON标记的联合

在Go中解组JSON标记的联合
EN

Stack Overflow用户
提问于 2019-05-06 02:05:26
回答 1查看 1.3K关注 0票数 3

我正在尝试解封Google Actions的JSON请求。它们具有如下所示的标记联合数组:

代码语言:javascript
复制
{
    "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
    "inputs": [{
      "intent": "action.devices.QUERY",
      "payload": {
        "devices": [{
          "id": "123",
          "customData": {
            "fooValue": 74,
            "barValue": true,
            "bazValue": "foo"
          }
        }, {
          "id": "456",
          "customData": {
            "fooValue": 12,
            "barValue": false,
            "bazValue": "bar"
          }
        }]
      }
    }]
}

{
    "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
    "inputs": [{
      "intent": "action.devices.EXECUTE",
      "payload": {
        "commands": [{
          "devices": [{
            "id": "123",
            "customData": {
              "fooValue": 74,
              "barValue": true,
              "bazValue": "sheepdip"
            }
          }, {
            "id": "456",
            "customData": {
              "fooValue": 36,
              "barValue": false,
              "bazValue": "moarsheep"
            }
          }],
          "execution": [{
            "command": "action.devices.commands.OnOff",
            "params": {
              "on": true
            }
          }]
        }]
      }
    }]
}

etc.

显然,我可以将其分解为一个interface{},并使用完全动态的类型转换和一切来解码它,但是Go对结构的解码有很好的支持。有没有办法在Go中优雅地做到这一点(例如like you can in Rust)?

我觉得你几乎可以通过阅读demarshalling to this来实现它:

代码语言:javascript
复制
type Request struct {
    RequestId string
    Inputs    []struct {
        Intent   string
        Payload  interface{}
    }
}

然而,一旦你有了Payload interface{},似乎就没有任何方法可以将它反序列化到struct中(除了序列化它并再次反序列化它,这很糟糕。有什么好的解决方案吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-06 02:52:40

您可以将Payload存储为interface{},而不是将其解组为json.RawMessage,然后根据意图的值对其进行解组。这如json文档中的示例所示:

https://golang.org/pkg/encoding/json/#example_RawMessage_unmarshal

将该示例与您的JSON和struct结合使用,您的代码将如下所示:

代码语言:javascript
复制
type Request struct {
    RequestId string
    Inputs    []struct {
        Intent   string
        Payload  json.RawMessage
    }
}

var request Request
err := json.Unmarshal(j, &request)
if err != nil {
    log.Fatalln("error:", err)
}
for _, input := range request.Inputs {
    var payload interface{}
    switch input.Intent {
    case "action.devices.EXECUTE":
        payload = new(Execute)
    case "action.devices.QUERY":
        payload = new(Query)
    }
    err := json.Unmarshal(input.Payload, payload)
    if err != nil {
        log.Fatalln("error:", err)
    }
    // Do stuff with payload
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55994888

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档