英文:
What's the proper way to convert a json.RawMessage to a struct?
问题
我有这个struct:
type SyncInfo struct {
Target string
}
现在我从ElasticSearch查询一些json数据。Source的类型是json.RawMessage。
我想要的只是将source映射到我创建的SyncInfo,我为此创建了变量mySyncInfo。
我已经找到了如何做到这一点...但感觉有点奇怪。我首先调用MarshalJSON()来获取一个[]byte,然后将其传递给json.Unmarshal(),它接受一个[]byte和指向我的结构体的指针。
这样做可以正常工作,但感觉好像多了一步。我是否漏掉了什么,或者这是从json.RawMessage到struct的预期方式?
var mySyncInfo SyncInfo
jsonStr, _ := out.Hits.Hits[0].Source.MarshalJSON()
json.Unmarshal(jsonStr, &mySyncInfo)
fmt.Print(mySyncInfo.Target)
以上是翻译好的内容,请确认是否正确。
英文:
I have this struct
type SyncInfo struct {
Target string
}
Now I query some json data from ElasticSearch. Source is of type json.RawMessage.
All I want is to map source to my SyncInfo which I created the variable mySyncInfo for.
I even figured out how to do that...but it seems weird. I first call MarshalJSON() to get a []byte and then feed that to json.Unmarshal() which takes an []byte and a pointer to my struct.
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.RawMessage to a struct?
var mySyncInfo SyncInfo
jsonStr, _ := out.Hits.Hits[0].Source.MarshalJSON()
json.Unmarshal(jsonStr, &mySyncInfo)
fmt.Print(mySyncInfo.Target)
答案1
得分: 40
如上所述,json.RawMessage 的底层类型是 []byte,因此您可以将 json.RawMessage 作为数据参数传递给 json.Unmarshal。
然而,您的问题在于您有一个指针(*json.RawMessage)而不是一个值。您只需要对其进行解引用:
err := json.Unmarshal(*out.Hits.Hits[0].Source, &mySyncInfo)
工作示例:
package main
import (
"encoding/json"
"fmt"
)
type SyncInfo struct {
Target string
}
func main() {
data := []byte(`{"target": "localhost"}`)
Source := (*json.RawMessage)(&data)
var mySyncInfo SyncInfo
// 注意解引用的星号 *
err := json.Unmarshal(*Source, &mySyncInfo)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", mySyncInfo)
}
输出:
{Target:localhost}
Playground: http://play.golang.org/p/J8R3Qrjrzx
英文:
As said, the underlying type of json.RawMessage is []byte, so you can use a json.RawMessage as the data parameter to 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:
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
答案2
得分: 4
json.RawMessage实际上只是一个字节切片。你可以直接将它传递给json.Unmarshal,像这样:
json.Unmarshal(out.Hits.Hits[0].Source, &mySyncInfo)
另外,虽然与此无关,但json.Unmarshal可能会返回一个错误,你需要处理它:
err := json.Unmarshal(*out.Hits.Hits[0].Source, &mySyncInfo)
if err != nil {
// 处理错误
}
英文:
json.RawMessage is really just a slice of bytes. You should be able to feed it directly into json.Unmarshal directly, like so:
json.Unmarshal(out.Hits.Hits[0].Source, &mySyncInfo)
Also, somewhat unrelated, but json.Unmarshal can return an error and you want to handle that.
err := json.Unmarshal(*out.Hits.Hits[0].Source, &mySyncInfo)
if err != nil {
// Handle
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论