我正在尝试解封Google Actions的JSON请求。它们具有如下所示的标记联合数组:
{
"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来实现它:
type Request struct {
RequestId string
Inputs []struct {
Intent string
Payload interface{}
}
}然而,一旦你有了Payload interface{},似乎就没有任何方法可以将它反序列化到struct中(除了序列化它并再次反序列化它,这很糟糕。有什么好的解决方案吗?
发布于 2019-05-06 02:52:40
您可以将Payload存储为interface{},而不是将其解组为json.RawMessage,然后根据意图的值对其进行解组。这如json文档中的示例所示:
https://golang.org/pkg/encoding/json/#example_RawMessage_unmarshal
将该示例与您的JSON和struct结合使用,您的代码将如下所示:
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
}https://stackoverflow.com/questions/55994888
复制相似问题