英文:
Marshal of json.RawMessage
问题
请在这里找到代码:http://play.golang.org/p/zdQ14ItNBZ
我将JSON数据保存为RawMessage,但无法解码它。我需要包含的结构体进行编组和解组,但我仍然希望能够获取JSON字段。
代码:
package main
import (
"encoding/json"
"fmt"
)
type Data struct {
Name string
Id int
Json json.RawMessage
}
type Data2 struct {
Name string
Id int
}
func main() {
tmp := Data2{"World", 2}
b, err := json.Marshal(tmp)
if err != nil {
fmt.Println("Error %s", err.Error())
}
fmt.Println("b %s", string(b))
test := Data{"Hello", 1, b}
b2, err := json.Marshal(test)
if err != nil {
fmt.Println("Error %s", err.Error())
}
fmt.Println("b2 %s", string(b2))
var d Data
err = json.Unmarshal(b2, &d)
if err != nil {
fmt.Println("Error %s", err.Error())
}
fmt.Println("d.Json %s", string(d.Json))
var tmp2 Data2
err = json.Unmarshal(d.Json, &tmp2)
if err != nil {
fmt.Println("Error %s", err.Error())
}
fmt.Println("Data2 %+v", tmp2)
}
输出:
b %s {"Name":"World","Id":2}
b2 %s {"Name":"Hello","Id":1,"Json":"eyJOYW1lIjoiV29ybGQiLCJJZCI6Mn0="}
d.Json %s "eyJOYW1lIjoiV29ybGQiLCJJZCI6Mn0="
Error %s json: cannot unmarshal string into Go value of type main.Data2
Data2 %+v { 0}
英文:
Please find the code here http://play.golang.org/p/zdQ14ItNBZ
I am keeping JSON data as RawMessage, but cannot decode it out. I need the containing struct to be Marshalled and Unmarshalled, but I would expect still be able to get the JSON field.
code:
package main
import (
"encoding/json"
"fmt"
)
type Data struct {
Name string
Id int
Json json.RawMessage
}
type Data2 struct {
Name string
Id int
}
func main() {
tmp := Data2{"World", 2}
b, err := json.Marshal(tmp)
if err != nil {
fmt.Println("Error %s", err.Error())
}
fmt.Println("b %s", string(b))
test := Data{"Hello", 1, b}
b2, err := json.Marshal(test)
if err != nil {
fmt.Println("Error %s", err.Error())
}
fmt.Println("b2 %s", string(b2))
var d Data
err = json.Unmarshal(b2, &d)
if err != nil {
fmt.Println("Error %s", err.Error())
}
fmt.Println("d.Json %s", string(d.Json))
var tmp2 Data2
err = json.Unmarshal(d.Json, &tmp2)
if err != nil {
fmt.Println("Error %s", err.Error())
}
fmt.Println("Data2 %+v", tmp2)
}
out:
b %s {"Name":"World","Id":2}
b2 %s {"Name":"Hello","Id":1,"Json":"eyJOYW1lIjoiV29ybGQiLCJJZCI6Mn0="}
d.Json %s "eyJOYW1lIjoiV29ybGQiLCJJZCI6Mn0="
Error %s json: cannot unmarshal string into Go value of type main.Data2
Data2 %+v { 0}
答案1
得分: 15
json.RawMessage上的所有方法都采用指针接收器,这就是为什么您无法利用它们的原因;您没有指针。
这种方式“可以”执行,但这可能不是您想要的策略:http://play.golang.org/p/jYvh8nHata
基本上,您需要这样做:
type Data struct {
Name string
Id int
Json *json.RawMessage
}
然后在程序的其余部分传播该更改。您实际上想要做什么?
英文:
the methods on json.RawMessage all take a pointer receiver, which is why you're not able to utilize any of them; you don't have a pointer.
This "works" in the sense that it executes, but this is likely not the strategy that you want: http://play.golang.org/p/jYvh8nHata
basically you need this:
type Data struct {
Name string
Id int
Json *json.RawMessage
}
and then propagate that change through the rest of your program. What... what are you actually trying to do?
答案2
得分: 7
jorellis的答案对于1.8版本之前的Go是正确的。
Go 1.8及更高版本将正确处理指针和非指针的json.RawMessage的编组。
修复提交:https://github.com/golang/go/commit/1625da24106b610f89ff7a67a11581df95f8e234
英文:
jorellis answer is correct for versions of Go before 1.8.
Go 1.8 and newer will correctly handle marshalling of both a pointer and non-pointer json.RawMessage.
Fixing commit: https://github.com/golang/go/commit/1625da24106b610f89ff7a67a11581df95f8e234
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论