【问题标题】:How can mapstructure use a discriminator to decode concrete typemapstructure如何使用鉴别器来解码具体类型
【发布时间】:2019-06-08 06:49:28
【问题描述】:

文档 (https://github.com/mitchellh/mapstructure) 提到了使用 mapstructure 进行解码的好处

{
  "type": "person",
  "name": "Mitchell"
}

我正在寻找一个显示解码过程的示例,例如解组 PersonPet

【问题讨论】:

    标签: json dictionary go


    【解决方案1】:

    该库仅将映射映射到结构。它不执行特定类型的解码。引用其文档:

    如果不先从 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}
    

    【讨论】:

    • 知道了。我是否可以在较低级别使用它,即如果在最高级别解码配置很好但在较低级别我需要一种或其他类型的操作?在 json 中,我将在 Action 上实现 Marshal 接口。如果超出范围,很高兴提出一个新问题。
    • @andig 您也可以在较低级别使用它。例如。创建已知的结构类型,它可能有一个map[string]interface{} 类型的字段。您可以检查另一个字段来决定将地图字段解码为什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 2022-01-16
    相关资源
    最近更新 更多