当 []byte 工作正常时无法封送 json.RawMessage

Yik*_*han 1 json marshalling go

可以在此处找到可重现的示例https://go.dev/play/p/wNyhezDfxVt

我想用字段封送 ( json.Marshal(...)) 一个结构体json.RawMessage

type Container1 struct {
    OldValue json.RawMessage `json:"old"`
    NewValue json.RawMessage `json:"new"`
}
Run Code Online (Sandbox Code Playgroud)

但是,它抱怨以下错误:

error calling MarshalJSON for type json.RawMessage: invalid character 'h' looking for beginning of value
Run Code Online (Sandbox Code Playgroud)

进行更改json.RawMessage[]byte解决问题,但请注意,这json.RawMessage只不过是[]byte

error calling MarshalJSON for type json.RawMessage: invalid character 'h' looking for beginning of value
Run Code Online (Sandbox Code Playgroud)

我想仍然能够使用json.RawMessage,有什么帮助吗?谢谢!

bla*_*een 5

该类型json.RawMessage应包含有效的 JSON,因为它将按原样(原始)序列化。

\n

当您使用 初始化json.RawMessage字段时[]byte("hello"),您将转换为[]byte字符串文字"hello",其内容hello 不带引号。然后json.Marshal会失败,因为您需要引号"才能使其成为有效的 JSON 字符串。要保留引号,您必须使用反引号括起来的未转义字符串文字。

\n

将结构的初始化更改为此将起作用:

\n
    c1 := Container1{\n        []byte(`"hello"`),\n        []byte(`"world"`),\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

尽管保持相同的字节内容,但[]bytein 中的切片不会\xe2\x80\x99 导致错误,这仅仅是因为默认将字节切片序列化为 base64。Container2json.Marshal

\n

事实上,修复游乐场后,两个输出 JSON 看起来不同:

\n

json.RawMessage

\n
{"old":"hello","new":"world"}\n
Run Code Online (Sandbox Code Playgroud)\n

[]byte

\n
{"old":"aGVsbG8=","new":"d29ybGQ="}\n
Run Code Online (Sandbox Code Playgroud)\n