看看这个游乐场:http://play.golang.org/p/dWku6SPqj5 http://play.golang.org/p/dWku6SPqj5
基本上,我正在工作的图书馆收到了interface{}
作为参数,然后需要json.Unmarshal
来自字节数组。在幕后,interface{}
参数是一个与字节数组的json结构匹配的结构,但库没有对该结构的引用(但它确实有对相应的reflect.Type的引用)。
为什么json包检测不到底层类型?由于某种原因,它返回一个简单的映射而不是实际的结构。
这是代码:
package main
import "fmt"
import "encoding/json"
import "reflect"
func main() {
good()
bad()
}
func good() {
var ping Ping = Ping{}
deserialize([]byte(`{"id":42}`), &ping)
fmt.Println("DONE:", ping.ID)
}
func bad() {
var ping interface{} = Ping{}
deserialize([]byte(`{"id":42}`), &ping)
fmt.Println("DONE:", ping) // It's a simple map now, not a Ping. Why?
}
func deserialize(stuff []byte, thing interface{}) {
value := reflect.ValueOf(thing)
fmt.Printf("%+v | %v\n", value, value.Kind())
err := json.Unmarshal(stuff, thing)
if err != nil {
panic(err)
}
}
type Ping struct {
ID int `json:"id"`
}
你已经传递到json
指向抽象接口的指针。你应该简单地传递一个指针Ping
as一个抽象接口:
func bad() {
var ping interface{} = &Ping{} // <<<< this
deserialize([]byte(`{"id":42}`), ping) // << and this
fmt.Println("DONE:", ping) // It's a simple map now, not a Ping. Why?
}
但如果正如你所说,你没有一个指针来强制转换interface{}
,您可以使用 Reflect 创建一个新指针,反序列化到其中,然后将值复制回来:
func bad() {
var ping interface{} = Ping{}
nptr := reflect.New(reflect.TypeOf(ping))
deserialize([]byte(`{"id":42}`), nptr.Interface())
ping = nptr.Interface()
fmt.Println("DONE:", ping) // It's a simple map now, not a Ping. Why?
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)