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

时间:2014-04-23 21:24:17

标签: json go

我有struct

type SyncInfo struct {
    Target string
}

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

我甚至想出了怎么做......但这看起来很奇怪。我首先致电mySyncInfo获取MarshalJSON(),然后将其提供给[]byte,其中json.Unmarshal()和指向我的结构的指针。

这种方法很好但感觉好像我正在做一个额外的跳跃。我错过了某些内容,或者是从[]byte转到json.RawMessage的预期方式吗?

struct

2 个答案:

答案 0 :(得分:20)

如上所述,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
    // Notice the dereferencing asterisk *
    err := json.Unmarshal(*Source, &mySyncInfo)
    if err != nil {
        panic(err)
    }

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

<强>输出:

{Target:localhost}

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

答案 1 :(得分:3)

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 {
    // Handle
}