英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论