查看此游乐场: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"`
}
答案 0 :(得分:3)
您已向json
传递指向抽象接口的指针。您只需将指向Ping
的指针作为抽象接口传递:
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?
}