使用自定义 MarshalJSON() 方法嵌入结构的惯用方式
鉴于下面的结构,我们可以轻松地将 Employee 结构编组为 JSON,如下所示预期:
type Person struct { Name string `json:"name"` } type Employee struct { *Person JobRole string `json:"jobRole"` }
但是,当嵌入结构有一个自定义的 MarshalJSON() 方法,它破坏了编组过程:
func (p *Person) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Name string `json:"name"` }{ Name: strings.ToUpper(p.Name), }) }
这是因为嵌入的 Person 结构实现了 MarshalJSON() 函数,该函数优先于 Employee 结构自己的 MarshalJSON() 方法。
所需的输出是正常对 Employee 字段进行编码,同时遵循 Person 的 MarshalJSON() 方法进行编组它的领域。但是,向 Employee 添加 MarshalJSON() 方法需要知道嵌入类型也实现 MarshalJSON(),这可能很脆弱。
要解决此问题,我们可以使用不同的方法:
创建一个新类型 Name 来代表 Person name:
type Name string
在 Name 上实现 MarshalJSON() 来自定义其编码:
func (n Name) MarshalJSON() ([]byte, error) { return json.Marshal(strings.ToUpper(string(n))) }
修改 Person 结构以使用 Name而不是string:
type Person struct { Name Name `json:"name"` }
此方法允许我们自定义 Person 名称的编码,而无需在 Employee 结构上使用 MarshalJSON() 方法。
或者,如果我们想要更通用地实现这一点,我们需要在外部类型上实现 MarshalJSON。内部类型上的方法被提升为外部类型,因此我们可以调用内部类型的 MarshalJSON 方法,将其输出解组为像 map[string]interface{} 这样的通用结构,并添加我们自己的字段。但是,这可能会产生更改最终输出字段的顺序的副作用。
以上是如何在 Go 中惯用地使用自定义'MarshalJSON()”方法嵌入结构?的详细内容。更多信息请关注PHP中文网其他相关文章!