gpt4 book ai didi

json - 为什么 json.Unmarshal 返回一个映射而不是预期的结构?

转载 作者:IT王子 更新时间:2023-10-29 00:45:38 27 4
gpt4 key购买 nike

查看这个 Playground :http://play.golang.org/p/dWku6SPqj5

基本上,我正在处理的库接收一个接口(interface){}作为参数,然后需要从字节数组中json.Unmarshal。在幕后,interface{} 参数是一个与字节数组的 json 结构相匹配的结构,但库没有对该结构的引用(但它确实有对相应的引用reflect.Type through).

为什么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"`
}

最佳答案

您已将指向抽象接口(interface)的指针传递给 json。您应该简单地将指针传递给 Ping 作为抽象接口(interface):

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?
}

关于json - 为什么 json.Unmarshal 返回一个映射而不是预期的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21468741/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com