鉴于以下结构:
type Person {
Name string `json:"name"`
}
type Employee {
Person
JobRole string `json:"jobRole"`
}
Run Code Online (Sandbox Code Playgroud)
我可以按照预期轻松地将Employee编组为JSON:
p := Person{"Bob"}
e := Employee{&p, "Sales"}
output, _ := json.Marshal(e)
fmt.Printf("%s\n", string(output))
Run Code Online (Sandbox Code Playgroud)
输出:
{ "名": "鲍勃", "jobRole": "销售"}
但是当嵌入式结构有一个自定义MarshalJSON()
方法时......
func (p *Person) MarshalJSON() ([]byte,error) {
return json.Marshal(struct{
Name string `json:"name"`
}{
Name: strings.ToUpper(p.Name),
})
}
Run Code Online (Sandbox Code Playgroud)
它彻底打破了:
p := Person{"Bob"}
e := Employee{&p, "Sales"}
output, _ := json.Marshal(e)
fmt.Printf("%s\n", string(output))
Run Code Online (Sandbox Code Playgroud)
现在结果是:
{ "名": "BOB"}
(注意显着缺乏jobRole
领域)
这很容易预料......嵌入式Person
结构实现了MarshalJSON()
被调用的函数.
麻烦的是,这不是我想要的.我想要的是:
{ "名": "BOB", "jobRole": "销售"}
也就是说,Employee
正常编码的字段,并推迟编组其字段Person
的MarshalJSON()
方法,并交回一些整洁的JSON.
现在,我可以一个添加MarshalJSON()
方法Employee
为好,但这个要求,我知道,嵌入式类型实现MarshalJSON()
,以及,或者(a)复制它的逻辑,或(b)调用Person
的MarshalJSON()
并以某种方式操纵它的输出,以适应,我想它.这两种方法看起来都很邋and,而且不是很有前途的证明(如果某天我不控制的嵌入式类型会增加一个自定义MarshalJSON()
方法怎么办?)
这里有没有我没有考虑的替代方案?
不要穿MarshalJSON
,Person
因为它被提升为外部类型.而是制定type Name string
并Name
实施MarshalJSON
.然后Person
改为
type Person struct {
Name Name `json:"name"`
}
Run Code Online (Sandbox Code Playgroud)
示例:https://play.golang.org/p/u96T4C6PaY
更新
为了更普遍地解决这个问题,你将不得不MarshalJSON
在外部类型上实现.内部类型的方法被提升为外部类型,所以你不会绕过它.你可以让外部类型调用内部类型,MarshalJSON
然后将其解组为通用结构,map[string]interface{}
并添加自己的字段.此示例执行此操作但它具有更改最终输出字段的顺序的副作用
https://play.golang.org/p/ut3e21oRdj
归档时间: |
|
查看次数: |
1239 次 |
最近记录: |