当前位置: 首页 > 面试题库 >

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

方斌
2023-03-14
问题内容

看到这个游乐场:http :
//play.golang.org/p/dWku6SPqj5

基本上,我正在使用的库interface{}将a作为参数接收,然后需要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"`
}

问题答案:

您已经传递了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?
}


 类似资料:
  • 问题内容: 我有一个看起来像这样的JSON Blob 我有一些代码将其转换回go结构 但是我在运行时看到的只是一个零位结构 我尝试先分配该结构,但那也没有用,我不确定为什么它不产生值,并且不返回错误 问题答案: 您的结构字段不会导出。这是因为它们以小写字母开头。 当我说“未导出”时,是指它们在您的包装之外不可见。您的软件包可以愉快地访问它们,因为它们在本地作用域内。 至于包装-它看不到它们。您需要

  • 问题内容: 据我所知,使用或实例化对象分别返回或的新实例。具有 新标识 的新实例对象。 在我实际测试它之前,这对我来说是很清楚的,我注意到它实际上返回了而不是预期的: 如预期的那样,分别使用和创建对象时,也会表现出这种行为: 我可以在状态文档中找到唯一相关的信息: […]例如,return和return 。 如果未提供任何参数,则构造函数将创建一个新的空元组。 可以说,这不足以回答我的问题。 那么

  • 问题内容: 为什么不: 代替: 获得唯一哈希码的更高机会? 问题答案: 因为数组的最大长度为。 由于的主要用途是确定将对象插入/ 的后备数组中的哪个插槽,因此hashcode> 将无法存储在该数组中。

  • 问题内容: 有人可以解释为什么我想要的结果“ hi”以字母“ b”开头并以换行符开头吗? 我正在使用 Python 3.3 如果我使用python 2.7运行此额外的“ b”,则不会出现 问题答案: 默认情况下,echo命令返回换行符 与此比较: 至于字符串前面的 b ,则表明它是一个字节序列,等效于Python 2.6+中的常规字符串 http://docs.python.org/3/refer

  • 本文向大家介绍Math.min() < Math.max() 返回结果是什么?为什么?相关面试题,主要包含被问及Math.min() < Math.max() 返回结果是什么?为什么?时的应答技巧和注意事项,需要的朋友参考一下 返回,因为返回,返回。 猜测的实现方式大致如下: 接受不定项参数,当参数只有一个的时候,例如,那么这个需要和(js中最小的数)进行比较,所以结果返回,哪怕传入的值再小,单个