我试图写一个简单的自定义封送拆收器,但失败了。注意,我有一个具有三个功能的接口。 Happy
和Sad
结构都通过嵌入实现所有三个必需功能的emotion
结构来实现此接口。
问题是,当我在指向UnmarshalJSON
或json.Unmarshal()
的指针上调用Happy
时,无法调用Sad
,但我不明白为什么。您可以在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)
}
最佳答案
您无法解组为抽象接口类型。
接口值只是一个指向类型的指针(与该类型的方法相关联),它没有任何存储空间,因为抽象类型无法知道将来可能具有的任何具体值的确切大小。
使用具体的值类型(也实现该接口)将起作用:
y2 := emotion{}
err = json.Unmarshal(jsonX, &y2)
游乐场: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/