首页 > 后端开发 > Golang > 如何使用自定义封送处理为嵌入式结构正确 MarshalJSON()?

如何使用自定义封送处理为嵌入式结构正确 MarshalJSON()?

Linda Hamilton
发布: 2024-12-07 10:40:16
原创
810 人浏览过

How to Correctly MarshalJSON() for Embedded Structs with Custom Marshaling?

使用自定义 MarshalJSON() 方法嵌入结构的惯用方法

问题:

我们如何使用具有自定义 MarshalJSON() 方法的嵌入式结构?预期的输出是保留嵌入结构的自定义封送处理,同时对外部结构的字段进行编码。

示例:

type Person struct {
    Name string `json:"name"`
}

type Employee struct {
    *Person
    JobRole string `json:"jobRole"`
}
登录后复制

当嵌入的 Person struct 有一个自定义 MarshalJSON() 方法:

func (p *Person) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct {
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(p.Name),
    })
}
登录后复制

编组 Employee 实例会中断,导致位于:

{"name": "BOB"}
登录后复制

解决方案:

不要在 Person 上实现 MarshalJSON(),而是创建一个实现 MarshalJSON() 的新 Name 类型。然后,修改 Person 以使用此名称类型:

type Name string

func (n Name) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct {
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(string(n)),
    })
}

type Person struct {
    Name Name `json:"name"`
}
登录后复制

这允许将自定义封送逻辑应用于 Name 字段,同时仍按预期对 Employee 字段进行编码。

通用解决方案:

对于更通用的解决方案,在外部结构上实现 MarshalJSON() 。当内部类型上的方法提升为外部类型时,外部类型可以将结果解组为通用结构(如map[string]interface{})并添加自己的字段。

示例:

type Person struct {
    Name string `json:"name"`
}

type Employee struct {
    *Person
    JobRole string `json:"jobRole"`
}

func (e *Employee) MarshalJSON() ([]byte, error) {
    b, err := e.Person.MarshalJSON()
    if err != nil {
        return nil, err
    }

    var m map[string]interface{}
    if err := json.Unmarshal(b, &m); err != nil {
        return nil, err
    }

    m["jobRole"] = e.JobRole
    return json.Marshal(m)
}
登录后复制

以上是如何使用自定义封送处理为嵌入式结构正确 MarshalJSON()?的详细内容。更多信息请关注PHP中文网其他相关文章!

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