将 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
What's the proper way to convert a json.RawMessage to a struct?
提问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
回答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
}

