首页 > 后端开发 > Golang > 当使用 Go 的 `json.Unmarshal` 和 `interface{}` 时,如何有效地将 JSON 数据解组到特定的结构中?

当使用 Go 的 `json.Unmarshal` 和 `interface{}` 时,如何有效地将 JSON 数据解组到特定的结构中?

Mary-Kate Olsen
发布: 2024-12-26 13:44:10
原创
380 人浏览过

How Can I Efficiently Unmarshal JSON Data into Specific Structs When Using Go's `json.Unmarshal` with `interface{}`?

解组为 Interface{} 和类型断言

问题陈述

使用 Go 的 json.Unmarshal 解码字符串时从消息系统中发现结果是map[string]interface{}而不是预期的结构类型(Somthing1 或 Somthing2),使得类型断言不可能。

根本原因

json.Unmarshal 函数,当解组到接口{}时,默认值已知类型,如 []interface{} 和 map[string]interface{}。在给定的代码中,接口变量输入接收表示未编组的 JSON 数据的 map[string]interface{},但 switch 语句尝试直接将其断言为 Somthing1 或 Somthing2。

解决方案

由于 JSON 本身并未解组到所需的结构中,因此有两个选项可以解决此问题问题:

1。从通用映射中检查和转换:

一种方法是检查 map[string]interface{} 并手动将数据解包到适当的结构类型中。但是,这需要仔细处理潜在错误并手动分配值。

2.使用自定义 JSON 解组器:

更简洁的解决方案是创建自定义 JSON 解组器来处理解组过程。此自定义解组器可以根据 JSON 数据识别正确的结构类型并相应地对其进行解组。以下是此类解组器的示例:

type Unpacker struct {
    Data       interface{}
}

func (u *Unpacker) UnmarshalJSON(b []byte) error {
    smth1 := &Something1{}
    err := json.Unmarshal(b, smth1)

    // no error, but we also need to make sure we unmarshaled something
    if err == nil && smth1.Thing != "" {
        u.Data = smth1
        return nil
    }

    // abort if we have an error other than the wrong type
    if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok {
        return err
    }

    smth2 := &Something2{}
    err = json.Unmarshal(b, smth2)
    if err != nil {
        return err
    }

    u.Data = smth2
    return nil
}
登录后复制

通过将此自定义解组器的实例传递给 json.Unmarshal,生成的 Data 字段将包含正确结构类型的解组数据,从而允许无缝类型断言.

以上是当使用 Go 的 `json.Unmarshal` 和 `interface{}` 时,如何有效地将 JSON 数据解组到特定的结构中?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板