gpt4 book ai didi

go - 如何正确覆盖 UnmarshalJSON?

转载 作者:数据小太阳 更新时间:2023-10-29 03:08:40 25 4
gpt4 key购买 nike

我正在尝试编写一个简单的自定义编码(marshal)拆收器,但失败了。请注意,我有一个具有三个功能的界面。 HappySad 结构都通过嵌入实现所有三个必需功能的 emotion 结构来实现此接口(interface)。

问题是当我在指向 Happy 的指针上调用 json.Unmarshal() 时,UnmarshalJSON 没有被调用伤心,我不明白为什么。您可以在 Go Playground 中重现确切的代码库或者只是看看下面。您会注意到,虽然 MarshalJSON 被正确调用,但 UnmarshalJSON 却没有。

type Emotion interface {
String() string
MarshalJSON() ([]byte, error)
UnmarshalJSON(data []byte) error
}

type emotion struct {
status string
}

func (s emotion) String() string {
return s.status
}

func (s emotion) MarshalJSON() ([]byte, error) {
fmt.Println("MarshalJSON is overriden: I am called fine")
x := struct {
Status string
}{
Status: s.String(),
}

return json.Marshal(x)
}

func (s *emotion) UnmarshalJSON(data []byte) error {
fmt.Println("MarshalJSON is overriden: I am never called")
y := struct {
Status string
}{
Status: "",
}

err := json.Unmarshal(data, &y)
if err != nil {
return err
}

s.status = y.Status
return nil
}

type Happy struct {
*emotion
}

// Job is not in any detention
type Sad struct {
*emotion
}


func main() {
x := Happy{&emotion{status: "happy"}}
jsonX, _ := json.Marshal(x)
var y Emotion
err := json.Unmarshal(jsonX, &y)
fmt.Printf("%v", err)
}

最佳答案

您不能解码为抽象接口(interface)类型。接口(interface)值只是一个指向类型的指针(关联该类型的方法)——它背后没有存储空间——因为抽象类型无法知道它将来可能拥有的任何具体值的确切大小。

使用具体的值类型(也实现了该接口(interface))将起作用:

y2 := emotion{}
err = json.Unmarshal(jsonX, &y2)

Playground :https://play.golang.org/p/8aCEjLgfKVQ

MarshalJSON is overriden: I am called fine
EXPECTED ERROR, Can't unmarshal into a non-concrete value: json: cannot unmarshal object into Go value of type main.Emotion

MarshalJSON is overriden: I am (fixed) and now called
SHOULD NOT ERROR: <nil>
VALUE: happy

关于go - 如何正确覆盖 UnmarshalJSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56469322/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com