前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
通过代码描述一下这里的具体操作:
type Parent interface { Test() } type Child struct { Name string `json:"name"` } func (c Child) Test() { } func createChild() Parent { return Child{} } func test() Parent { // c 是一个 Parent 类型 c := createChild() s := `{"name":"123"}` err := json.Unmarshal([]byte(s), &c) if err != nil { panic(err) } // 问题:这里能不能得到 name 的值 123? fmt.Printf("name=%s\n", c.(Child).Name) return c }
答案:不行。
问题描述
具体就是,我有一个结构体 Child
实现了接口 Parent
,然后 Child
里面有 name
属性,然后在反序列化的时候,用指向 Parent
,类型的值来接收。
结果就是,结构体里面字段都丢失了。
如果我们写成下面这样,就可能错过了发现错误的机会(我一开始就是这么写的):
_ = json.Unmarshal([]byte(s), &c)
如果打印错误的话,其实编译器已经给出了明确的报错信息:
panic: json: cannot unmarshal object into Go value of type body.Parent [recovered] panic: json: cannot unmarshal object into Go value of type body.Parent
原因
在反序列化的时候,反射处理是拿不到那个值的具体类型的。
参考链接:https://stackoverflow.com/questions/32428797/unmarshal-to-a-interface-type
原答案:
You can marshal from an interface type variable, because the object exists locally, so the reflector knows the underlying type.
You cannot unmarshal to an interface type, because the reflector does not know which concrete type to give to a new instance to receive the marshaled data.