Struct含有匿名字段,该匿名字段有MarshalJSON方法,导致Struct不能正确转换成json字符串!!

harrykobe · 2017-01-22 03:24:45 · 2116 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-01-22 03:24:45 的主题,其中的信息可能已经有所发展或是发生改变。

这是问题的原地址: http://stackoverflow.com/questions/38489776/idiomatic-way-to-embed-struct-with-custom-marshaljson-method

目前我遇到,解决方法是有的,但找不到比较好的解决方法,具体我用中文重新表述问题。

给出下面的一个结构:

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

type Employee {
    Person
    JobRole string `json:"jobRole"`
}

我可以很轻松地转换成我想需要的JSON字符串格式,例子如下:

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),
    })
}

同样的输出代码:

p := Person{"Bob"}
e := Employee{&p, "Sales"}
output, _ := json.Marshal(e)
fmt.Printf("%s\n", string(output))

结果却变了

{"name":"BOB"}

很明显,这个输出缺少了jobRole字段的内容

我们很容易知道原因,因为里面的匿名字段Person结构体实现了MarshalJSON()方法,所以这个方法被调用了。

麻烦的是,这不是我想要的结果,我想要的结果是这样的:

{"name":"BOB","jobRole":"Sales"}

现在,我添加了一个MarshalJSON()方法到Employee结构体中,如下:

func (e *Employee) MarshalJSON() ([]byte,error) {
    return json.Marshal(struct{
        Person
        JobRole string `json:"jobRole"`
    }{
        Person: e.Person,
        JobRole: e.JobRole,
    })
}

但我仍要输出匿名字段Person的内容,那么就必定会调用Person结构体里面的MarshalJSON()方法,这样一下,整个过程变成了一个死循环,得出的结果仍然是:

{"name":"BOB"}

变成了一个“先有鸡还是先有蛋”的过程。

大家有没有什么好的办法解决?


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2116 次点击  
加入收藏 微博
4 回复  |  直到 2017-01-23 16:44:16
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传