看到这个游乐场:http : //play.golang.org/p/dWku6SPqj5
基本上,我正在使用的库interface{}将a作为参数接收,然后需要json.Unmarshal从字节数组中获取。在幕后,该interface{}参数是一个与字节数组的json结构匹配的结构,但该库没有对该结构的引用(但它确实具有对相应的reflect.Type through的引用)。
interface{}
json.Unmarshal
为什么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 作为 抽象接口传递:
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? }
但是,如您所说,如果您没有指针可以转换为an 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? }