英文:
json.Unmarshal nested object into string or []byte
问题
我正在尝试解析一些 JSON 数据,以便将嵌套对象视为 string
或 []byte
,而不是解析它。
所以我想要得到以下结果:
{
"id" : 15,
"foo" : { "foo": 123, "bar": "baz" }
}
解析为:
type Bar struct {
ID int64 `json:"id"`
Foo []byte `json:"foo"`
}
我得到了以下错误:
json: cannot unmarshal object into Go value of type []uint8
英文:
I'm trying to Unmarshal some json so that a nested object does not get parsed but just treated as a string
or []byte
.
So I want to get the following:
{
"id" : 15,
"foo" : { "foo": 123, "bar": "baz" }
}
Unmarshaled into:
type Bar struct {
ID int64 `json:"id"`
Foo []byte `json:"foo"`
}
I get the following error:
json: cannot unmarshal object into Go value of type []uint8
答案1
得分: 56
我认为你正在寻找的是encoding/json
包中的RawMessage
类型。
文档中说明:
type RawMessage []byte
RawMessage是一个原始编码的JSON对象。它实现了Marshaler和Unmarshaler接口,可以用于延迟JSON解码或预先计算JSON编码。
以下是使用RawMessage的工作示例:
package main
import (
"encoding/json"
"fmt"
)
var jsonStr = []byte(`{
"id" : 15,
"foo" : { "foo": 123, "bar": "baz" }
}`)
type Bar struct {
Id int64 `json:"id"`
Foo json.RawMessage `json:"foo"`
}
func main() {
var bar Bar
err := json.Unmarshal(jsonStr, &bar)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", bar)
}
输出结果:
{Id:15 Foo:[123 32 34 102 111 111 34 58 32 49 50 51 44 32 34 98 97 114 34 58 32 34 98 97 122 34 32 125]}
英文:
I think what you are looking for is the RawMessage type in the encoding/json
package.
The documentation states:
>type RawMessage []byte
>
RawMessage is a raw encoded JSON object. It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding.
Here is a working example of using RawMessage:
package main
import (
"encoding/json"
"fmt"
)
var jsonStr = []byte(`{
"id" : 15,
"foo" : { "foo": 123, "bar": "baz" }
}`)
type Bar struct {
Id int64 `json:"id"`
Foo json.RawMessage `json:"foo"`
}
func main() {
var bar Bar
err := json.Unmarshal(jsonStr, &bar)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", bar)
}
Output:
> {Id:15 Foo:[123 32 34 102 111 111 34 58 32 49 50 51 44 32 34 98 97 114 34 58 32 34 98 97 122 34 32 125]}
答案2
得分: 3
Foo类型是一个map[string]string,所以要正确定义Foo:
type Bar struct {
id int64
Foo map[string]string
}
认为这样会更好。
英文:
The Foo type is a map[string]string so define Foo correctly:
type Bar struct {
id int64
Foo map[string]string
}
Think that would work better
答案3
得分: 2
定义一个实现Unmarshaler
接口的类型可以让你访问被解析的[]byte
。
type Prefs []byte
func (p *Prefs) UnmarshalJSON(b []byte) error {
*p = make(Prefs, len(b))
copy(*p, b)
return nil
}
英文:
Defining a type which implements the Unmarshaler
interface gives you access to the []byte
's being parsed.
type Prefs []byte
func (p *Prefs) UnmarshalJSON(b []byte) error {
*p = make(Prefs, len(b))
copy(*p, b)
return nil
}
答案4
得分: -1
经过一番调试,我发现在你的游乐场演示中,最大的问题是将 JSON 类型转换为 []byte 类型。为了理解我的意思,可以查看这个游乐场链接:http://play.golang.org/p/M0706KCZbh
如果你运行它,你会注意到类型转换切片和编组切片之间的 []byte 在 'Prefs' 变量周围有所不同。
从结构体编组的 JSON:
[123 34 105 100 34 58 49 53 44 34 112 114 101 102 115 34 58 34 101 121 65 105 90...
类型转换的 []byte:
[123 34 105 100 34 58 49 53 44 34 112 114 101 102 115 34 58 123 34 102 111 111 34...
我已经删除了空格,以尽可能地对齐。从中可以得出的主要结论是,类型转换不会产生与通过 json.Marshal 方法运行数据相同的结果,为了使其工作,你需要一个自定义类型来处理 JSON 包无法识别的反编组。
英文:
After a bit of tinkering I've found that in your playground demo the biggest problem is the typecasting of the json to a []byte. To see what I mean by that, take a look a this playground: http://play.golang.org/p/M0706KCZbh
If you run it, you'll notice the []byte between the typecast slice and the marshaled slice differ around the point of the 'Prefs' variable.
json marshaled from struct
[123 34 105 100 34 58 49 53 44 34 112 114 101 102 115 34 58 34 101 121 65 105 90...
typecast []byte
[123 34 105 100 34 58 49 53 44 34 112 114 101 102 115 34 58 123 34 102 111 111 34...
I've removed white space to try and make it line up as much as possible. The main takeaway from this is that typecasting does not produce the same results as running the data through the json.Marshal method and to make this work you would need a custom type to handle the unmarshaling of what the json package does not recognize.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论