json.Unmarshal 嵌套对象成字符串或 []byte
Posted
技术标签:
【中文标题】json.Unmarshal 嵌套对象成字符串或 []byte【英文标题】:json.Unmarshal nested object into string or []byte 【发布时间】:2013-12-04 19:12:53 【问题描述】:我正在尝试解组一些 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
playground demo
【问题讨论】:
为什么不使用map[string]interface
?它还具有以正确方式重新编组的优点。
@JamesHolmes 通常不建议这样做,因为这允许任何类型,如果您不明确希望支持所有类型,请不要使用空接口(接口),它会导致您比它解决的问题更多
【参考方案1】:
我认为您正在寻找的是 RawMessage 包中的 encoding/json
类型。
文档说明:
输入 RawMessage []字节
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]
Playground
【讨论】:
这正是我想要的 告诉过你 ;) 。很高兴为您提供帮助! 我得到了那个输出,但是我该如何使用它呢?【参考方案2】:Foo 类型是一个 map[string]string,所以正确定义 Foo:
type Bar struct
id int64
Foo map[string]string
觉得这样会更好
【讨论】:
所以[]bytes
-> Unmarshal
-> map[string]interface
-> Marshal
-> string
... 为什么?【参考方案3】:
定义实现Unmarshaler
接口的类型使您可以访问正在解析的[]byte
。
type Prefs []byte
func (p *Prefs) UnmarshalJSON(b []byte) error
*p = make(Prefs, len(b))
copy(*p, b)
return nil
playground demo
【讨论】:
【参考方案4】:经过一番修改后,我发现在您的游乐场演示中,最大的问题是将 json 类型转换为 []byte。要了解我的意思,请看一下这个游乐场:http://play.golang.org/p/M0706KCZbh
如果你运行它,你会注意到 typecast slice 和 marshaled slice 之间的 []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...
类型转换 []字节
[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 包无法识别的内容的解组。
【讨论】:
我认为这个例子更好地传达了你所说的 play.golang.org/p/1XFn6zqME8 。然而,它并没有真正回答这个问题。以上是关于json.Unmarshal 嵌套对象成字符串或 []byte的主要内容,如果未能解决你的问题,请参考以下文章
go json.Unmarshal报错invalid character ' ï' looking for beginning of value