繁体   English   中英

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

[英]json.Unmarshal fails when embedded type has UnmarshalJSON

我正在尝试解组具有嵌入类型的结构。 当嵌入类型具有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'

...所以两个自定义的unmarshal函数都运行了。 嵌入式结构中的值是正确的,但外部结构的值将丢失。

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

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

这是预料之中的。

创建别名时:

type Alias Foo

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

但是 ,嵌入式EmbeddedStructUnmarshalJSON方法将被提升!

因此, Alias将使用UnmarshalJSON方法,该方法仅解组EmbeddedStruct的值,而不是使用您需要的默认解组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM