首页 > 后端开发 > Golang > 如何在 Go 嵌入式结构中保留自定义编组?

如何在 Go 嵌入式结构中保留自定义编组?

DDD
发布: 2024-12-17 19:07:10
原创
852 人浏览过

How to Preserve Custom Marshalling in Go Embedded Structs?

保留嵌入式结构的自定义编组

在 Go 中,将一个结构嵌入到另一个结构中是继承功能的常见方法。但是,当嵌入结构具有自定义 MarshalJSON() 方法时,可能会出现问题。本文探讨了这一挑战的解决方案,确保外部结构可以正常编组其字段,同时仍然利用嵌​​入结构的自定义编组。

考虑以下结构:

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

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

通常,将 Employee 编组为 JSON 会产生预期的输出:

p := Person{"Bob"}
e := Employee{&p, "Sales"}
output, _ := json.Marshal(e)
fmt.Printf("%s\n", string(output))
// Output: {"name":"Bob","jobRole":"Sales"}
登录后复制

但是,为嵌入的 Person 结构引入自定义 MarshalJSON() 方法会更改此行为:

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

现在,编组 Employee 只会生成大写的名称:

output, _ := json.Marshal(e)
fmt.Printf("%s\n", string(output))
// Output: {"name":"BOB"}
登录后复制

要解决此问题,需要一个可能会尝试将 MarshalJSON() 方法添加到外部 Employee 结构。但是,这种方法需要了解嵌入类型的自定义编组,这可能并不总是实用。

更通用的解决方案涉及直接在外部类型上实现 MarshalJSON():

// Note: not on Person
func (e *Employee) MarshalJSON() ([]byte, error) {
    inner, err := json.MarshalIndent((*e.Person).(*Person), "", "    ")
    if err != nil {
        return nil, err
    }

    b := []byte(strings.Replace(string(inner), "}", "}", -1))
    b = append(b, []byte(`,"jobRole":"`+e.JobRole+`"}`)...)

    return b, nil
}
登录后复制

此方法调用嵌入结构的 MarshalJSON() 方法,将结果转换为映射,并添加外部结构的字段以生成所需的 JSON 输出。请注意,它不会操作嵌入结构的自定义编组。

或者,可以使用基于反射的方法:

func (e *Employee) MarshalJSON() ([]byte, error) {
    v := reflect.ValueOf(e).Elem()
    vf := v.FieldByName("Person")
    tmp, err := json.MarshalIndent(vf.Interface(), "", "    ")
    if err != nil {
        return nil, err
    }

    return []byte(strings.Replace(string(tmp), "}", `,"jobRole":"`+e.JobRole+`"}`, -1)), nil
}
登录后复制

此方法使用反射来访问嵌入结构的值和字段,无需依赖结构知识即可实现自定义编组。

通过在外部类型上实现 MarshalJSON(),这种方法确保嵌入结构和外部结构的字段都正确编组,保留所需的输出。

以上是如何在 Go 嵌入式结构中保留自定义编组?的详细内容。更多信息请关注PHP中文网其他相关文章!

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