了解如何将 JSON 解组到 Interface{} 是 Go 开发者的一项关键技能。在本文中,我们将通过一个实际示例来重点介绍与将 JSON 解组到具有 interface{} 字段的结构体相关的陷阱和解决方案。
考虑以下类型定义:
type Message struct { Cmd string `json:"cmd"` Data interface{} `json:"data"` } type CreateMessage struct { Conf map[string]int `json:"conf"` Info map[string]int `json:"info"` }
给定一个表示创建消息的 JSON 字符串,我们可能会尝试将其解码为消息struct:
{"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}
import "encoding/json" var data = []byte(`{"cmd":"create","data":{"conf":{"a":1},"info":{"b":2}}`) var m Message if err := json.Unmarshal(data, &m); err != nil { log.Fatal(err) }
在检查未编组的 Message 结构时,我们注意到 Data 字段仍然是一个 map[string]interface{}:
{Cmd:create Data:map[conf:map[a:1] info:map[b:2]]}
为了克服这一限制,我们采用了双管齐下的方法方法:
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") } }
通过采用这种技术,我们可以成功将 JSON 数据解组到 Message 结构中,其中 Data 字段包含变体 CreateMessage 类型。请参阅提供的游乐场示例以获取完整的实现。
以上是如何在 Go 中有效地将 JSON 解组到 Interface{} 中?的详细内容。更多信息请关注PHP中文网其他相关文章!