当嵌入结构定义自定义 MarshalJSON() 方法时,就会出现挑战,导致意外的 JSON 序列化行为当试图编组包含struct.
考虑以下结构定义:
type Person struct { Name string `json:"name"` } type Employee struct { *Person JobRole string `json:"jobRole"` }
按预期编组 Employee 结构很简单:
p := Person{"Bob"} e := Employee{&p, "Sales"} output, _ := json.Marshal(e) fmt.Printf("%s\n", string(output))
输出:
{"name":"Bob","jobRole":"Sales"}
但是,为嵌入结构定义自定义 MarshalJSON() 方法(如下所示)会破坏预期的序列化:
func (p *Person) MarshalJSON() ([]byte, error) { return json.Marshal(struct{ Name string `json:"name"` }{ Name: strings.ToUpper(p.Name), }) }
现在,编组 Employee 会生成带有 name 字段的输出转换为大写但缺少 jobRole 字段:
{"name":"BOB"}
为了维持所需的序列化行为,请避免在嵌入结构 (Person) 上定义 MarshalJSON() 方法。相反,创建一个封装自定义编组逻辑的单独类型并嵌入该类型:
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"` }
此方法将编组自定义隔离为专用类型,防止在其他地方嵌入 Person 结构时出现意外的副作用。
示例:https://play.golang.org/p/u96T4C6PaY
以上是如何在 Go 中惯用地嵌入带有自定义 `MarshalJSON()` 的结构?的详细内容。更多信息请关注PHP中文网其他相关文章!