嵌入类型具有UnmarshalJSON时json.Unmarshal失败 [英] json.Unmarshal fails when embedded type has UnmarshalJSON

查看:98
本文介绍了嵌入类型具有UnmarshalJSON时json.Unmarshal失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to unmarshal a struct that has an embedded type. When the embedded type has an UnmarshalJSON method, the unmarshaling of the outer type fails:

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'

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

... so both custom unmarshal functions ran. The value from the embedded struct is correct, but the value from the outer struct is lost.

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

If we simply remove the EmbeddedStruct.UnmarshalJSON method, it works as expected.

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

Am I doing something wrong? Is this expected? Or a bug? I'm sure there's a way I can tweak my UnmarshalJSON methods to get it working.

推荐答案

预期.

创建别名时:

type Alias Foo

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

Alias will not inherit the methods of Foo since it is a different type with a different method set, which is what you wanted to achieve to avoid an infinite recursion.

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

However, the embedded EmbeddedStruct's UnmarshalJSON method will instead be promoted!

因此,Alias将具有一个UnmarshalJSON方法,该方法只会解组EmbeddedStruct的值,而不是使用所需的默认解组.

So, Alias will have an UnmarshalJSON method that will only unmarshal EmbeddedStruct's value, instead of using the default unmarshalling that you desired.

这篇关于嵌入类型具有UnmarshalJSON时json.Unmarshal失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆