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

我正在尝试解组具有嵌入式类型的结构。当嵌入式类型具有UnmarshalJSON方法时,外部类型的解封将失败:

https://play.golang.org/p/Y_Tt5O8A1Q

package main

import (

"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.UnmarshalJSON

EmbeddedStruct.UnmarshalJSON

Foo: &{{embeddedValue} }

Unmarshal didn't work, Field value is . Should be 'value'

…因此两个自定义解组函数都运行了。来自嵌入式结构的值是正确的,但是来自外部结构的值将丢失。

如果我们只是删除EmbeddedStruct.UnmarshalJSON方法,它将按预期工作。

难道我做错了什么?这是预期的吗?还是一个错误?我确定有一种方法可以调整UnmarshalJSON方法以使其正常工作。

回答:

可以预料的。

创建别名时:

type Alias Foo

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

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

因此,Alias将有一个UnmarshalJSON仅能解组EmbeddedStruct值的方法,而不是使用所需的默认解组方法。

以上是 嵌入类型具有UnmarshalJSON时json.Unmarshal失败 的全部内容, 来源链接: utcz.com/qa/405359.html

回到顶部