问题:
我们如何使用具有自定义 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中文网其他相关文章!