我正在尝试编写一个简单的自定义封送拆收器,但失败了。请注意,我有一个具有三个功能的界面。Happy和结构体都通过嵌入实现所有三个必需功能的结构体Sad来实现此接口。emotion
问题是当我调用指向or 的指针UnmarshalJSON时不会被调用,我不明白为什么。您可以在Go Playground中重现确切的代码库或直接查看下面。您会注意到 while被正确调用,但不是。json.Unmarshal()HappySadMarshalJSONUnmarshalJSON
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)
}
Run Code Online (Sandbox Code Playgroud)
您无法解组为抽象接口类型。接口值只是指向类型的指针(关联类型方法) - 它后面没有存储 - 因为抽象类型无法知道它将来可能具有的任何具体值的确切大小。
使用具体的值类型(也实现该接口)将起作用:
y2 := emotion{}
err = json.Unmarshal(jsonX, &y2)
Run Code Online (Sandbox Code Playgroud)
游乐场: 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
Run Code Online (Sandbox Code Playgroud)