为了账号安全,请及时绑定邮箱和手机立即绑定

当嵌入类型具有 UnmarshalJSON 时,json.Unmarshal 失败

当嵌入类型具有 UnmarshalJSON 时,json.Unmarshal 失败

Go
千巷猫影 2021-09-27 21:19:15
我正在尝试解组具有嵌入类型的结构。当嵌入类型具有 UnmarshalJSON 方法时,外部类型的解组失败:https://play.golang.org/p/Y_Tt5O8A1Qpackage mainimport (    "fmt"    "encoding/json")type Foo struct {    EmbeddedStruct    Field string}func (d *Foo) UnmarshalJSON(from []byte) error {    fmt.Printf("Foo.UnmarshalJSON\n")    type Alias Foo    alias := &Alias{}    if err := json.Unmarshal(from, alias); err != nil {        return fmt.Errorf("Error in Foo.UnmarshalJSON: json.Unmarshal returned an error:\n%v\n", err)    }    *d = Foo(*alias)    return nil}type EmbeddedStruct struct {    EmbeddedField string}func (d *EmbeddedStruct) UnmarshalJSON(from []byte) error {    fmt.Printf("EmbeddedStruct.UnmarshalJSON\n")    type Alias EmbeddedStruct    alias := &Alias{}    if err := json.Unmarshal(from, alias); err != nil {        return fmt.Errorf("Error in EmbeddedStruct.UnmarshalJSON: json.Unmarshal returned an error:\n%v\n", err)    }    *d = EmbeddedStruct(*alias)    return nil}func main() {    data := `{"EmbeddedField":"embeddedValue", "Field": "value"}`    foo := &Foo{}    json.Unmarshal([]byte(data), foo)    fmt.Printf("Foo: %v\n", foo)    if foo.EmbeddedField != "embeddedValue" {        fmt.Printf("Unmarshal didn't work, EmbeddedField value is %v. Should be 'embeddedValue'\n", foo.EmbeddedField)    }    if foo.Field != "value" {        fmt.Printf("Unmarshal didn't work, Field value is %v. Should be 'value'\n", foo.Field)    }}输出是:Foo.UnmarshalJSONEmbeddedStruct.UnmarshalJSONFoo: &{{embeddedValue} }Unmarshal didn't work, Field value is . Should be 'value'...所以这两个自定义解组函数都运行了。嵌入结构中的值是正确的,但外部结构中的值丢失了。如果我们简单地删除 EmbeddedStruct.UnmarshalJSON 方法,它会按预期工作。难道我做错了什么?这是预期的吗?还是bug?我确信有一种方法可以调整我的 UnmarshalJSON 方法以使其正常工作。
查看完整描述

1 回答

?
慕侠2389804

TA贡献1719条经验 获得超6个赞

这是预期的。

创建别名时:

type Alias Foo

Alias不会继承 的方法,Foo因为它是具有不同方法集的不同类型,这是您想要避免无限递归的目标。

然而,内嵌EmbeddedStructUnmarshalJSON方法反而会得到提升!

因此,Alias将有一个UnmarshalJSON方法只解组EmbeddedStruct的值,而不是使用您想要的默认解组。


查看完整回答
反对 回复 2021-09-27
  • 1 回答
  • 0 关注
  • 317 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信