Marshal of json.RawMessage

huangapple go评论76阅读模式
英文:

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

huangapple
  • 本文由 发表于 2013年10月3日 03:25:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/19145202.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定