将 json.RawMessage 转换为结构的正确方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23255456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:17:16  来源:igfitidea点击:

What's the proper way to convert a json.RawMessage to a struct?

jsongo

提问by Christoph

I have this struct

我有这个 struct

type SyncInfo struct {
    Target string
}

Now I query some jsondata from ElasticSearch. Sourceis of type json.RawMessage. All I want is to map sourceto my SyncInfowhich I created the variable mySyncInfofor.

现在我json从 ElasticSearch查询一些数据。Source是 类型json.RawMessage。我想要的只是映射source到我SyncInfo为其创建变量的我mySyncInfo

I even figured out how to do that...but it seems weird. I first call MarshalJSON()to get a []byteand then feed that to json.Unmarshal()which takes an []byteand a pointer to my struct.

我什至想出了怎么做……但这似乎很奇怪。我首先调用MarshalJSON()get a[]byte然后将它提供给json.Unmarshal()它,它带有[]byte一个指向我的结构的指针。

This works fine but it feels as if I'm doing an extra hop. Am I missing something or is that the intended way to get from a json.RawMessageto a struct?

这工作正常,但感觉好像我在做一个额外的跳跃。我是否遗漏了什么,或者是从 ajson.RawMessage到 a的预期方式struct

var mySyncInfo SyncInfo

jsonStr, _ := out.Hits.Hits[0].Source.MarshalJSON()
json.Unmarshal(jsonStr, &mySyncInfo)

fmt.Print(mySyncInfo.Target)

回答by ANisus

As said, the underlying type of json.RawMessageis []byte, so you canuse a json.RawMessageas the data parameter to json.Unmarshal.

如前所述, 的基础类型json.RawMessage[]byte,因此您可以使用 ajson.RawMessage作为 的数据参数json.Unmarshal

However, your problem is that you have a pointer (*json.RawMessage) and not a value. All you have to do is to dereference it:

但是,您的问题是您有一个指针 ( *json.RawMessage) 而不是值。您所要做的就是取消引用它:

err := json.Unmarshal(*out.Hits.Hits[0].Source, &mySyncInfo)

Working example:

工作示例:

package main

import (
    "encoding/json"
    "fmt"
)

type SyncInfo struct {
    Target string
}

func main() {
    data := []byte(`{"target": "localhost"}`)
    Source := (*json.RawMessage)(&data)

    var mySyncInfo SyncInfo
    // Notice the dereferencing asterisk *
    err := json.Unmarshal(*Source, &mySyncInfo)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%+v\n", mySyncInfo)
}

Output:

输出:

{Target:localhost}

Playground:http://play.golang.org/p/J8R3Qrjrzx

游乐场:http : //play.golang.org/p/J8R3Qrjrzx

回答by Zach Latta

json.RawMessageis really just a slice of bytes. You should be able to feed it directly into json.Unmarshaldirectly, like so:

json.RawMessage实际上只是一个字节片。您应该可以直接将其输入json.Unmarshal,如下所示:

json.Unmarshal(out.Hits.Hits[0].Source, &mySyncInfo)

Also, somewhat unrelated, but json.Unmarshalcan return an error and you want to handle that.

此外,有些不相关,但json.Unmarshal可能会返回错误并且您想要处理它。

err := json.Unmarshal(*out.Hits.Hits[0].Source, &mySyncInfo)
if err != nil {
    // Handle
}