【发布时间】:2019-06-08 06:49:28
【问题描述】:
文档 (https://github.com/mitchellh/mapstructure) 提到了使用 mapstructure 进行解码的好处
{
"type": "person",
"name": "Mitchell"
}
我正在寻找一个显示解码过程的示例,例如解组 Person 或 Pet 类
【问题讨论】:
标签: json dictionary go
文档 (https://github.com/mitchellh/mapstructure) 提到了使用 mapstructure 进行解码的好处
{
"type": "person",
"name": "Mitchell"
}
我正在寻找一个显示解码过程的示例,例如解组 Person 或 Pet 类
【问题讨论】:
标签: json dictionary go
该库仅将映射映射到结构。它不执行特定类型的解码。引用其文档:
如果不先从 JSON 中读取“类型”字段,我们可能无法填充特定结构。我们总是可以对 JSON 的解码进行两次传递(首先读取“类型”,然后再读取其余部分)。但是,只需将其解码为
map[string]interface{}结构,读取“type”键,然后使用类似这个库的东西将其解码为正确的结构,就会简单得多。
它提供的只是您只需将 JSON 源解析一次,将其解析为映射,然后您可以自行决定需要映射或解组的类型。然后就可以使用已经构建好的map来填充你需要的类型了。
看这个例子:
type Person struct {
Name string `json:"name"`
}
type Credentials struct {
User string `json:"user"`
Password string `json:"password"`
}
func main() {
for _, src := range []string{srcPerson, srcCredentials} {
var m map[string]interface{}
if err := json.Unmarshal([]byte(src), &m); err != nil {
panic(err)
}
switch m["type"] {
case "person":
var p Person
if err := mapstructure.Decode(m, &p); err != nil {
panic(err)
}
fmt.Printf("%T %+v\n", p, p)
case "credentials":
var c Credentials
if err := mapstructure.Decode(m, &c); err != nil {
panic(err)
}
fmt.Printf("%T %+v\n", c, c)
}
}
}
const srcPerson = `{
"type": "person",
"name": "Mitchell"
}`
const srcCredentials = `{
"type": "credentials",
"user": "bob",
"password": "secret"
}`
输出:
main.Person {Name:Mitchell}
main.Credentials {User:bob Password:secret}
【讨论】:
map[string]interface{} 类型的字段。您可以检查另一个字段来决定将地图字段解码为什么。