我有个很不寻常的情况。我希望MarshalJSON有条件地省略一个struct字段。在下面的示例中,我们的想法是省略B Bool字段的输出,如果是B.Value == B.Undefined。
type Bool struct {
// Current value
Value bool
// Value if undefined
Undefined bool
}
func (b Bool) MarshalJSON() ([]byte, error) {
if b.Value == b.Undefined {
return []byte{}, nil
} else if b.Value {
return ([]byte)("true"), nil
}
return ([]byte)("false"), nil
}
func main() {
var example = struct {
N int `json:"foo"`
B Bool `json:"value,omitempty"`
}
example.B = Bool{true, true}
output, err := json.Marshal(example)
if err != nil {
panic(err)
}
fmt.Println(string(output))
}根据医生的说法:
如果字段的空值定义为false、0、nil指针、nil接口值以及任何空数组、切片、映射或字符串,则应从编码中省略该字段。
我返回一个空字节片,这将导致一个错误:
panic: json: error calling MarshalJSON for type main.Bool: unexpected end of JSON input
goroutine 1 [running]:
main.main()
/tmp/sandbox933539113/prog.go:32 +0x160如果我设置了example.B = Bool{false, true},那么它会打印结果,但是尽管从Bool.MarshalJSON返回了"false",但是这个字段仍然没有被省略。我做错了什么?一个类型满足Marshaler接口的值是否有效地忽略了省略标记条目?
发布于 2020-04-10 07:36:53
if b.Value == b.Undefined {
return []byte{}, nil生成无效的JSON:它返回0字节。您的MarshalJSON方法必须返回有效的JSON,这意味着它必须返回一些东西。
如果您的目标是完全省略该字段,则在未设置该字段时,请使用指针,不要设置:
func main() {
var example = struct {
N int `json:"foo"`
B *Bool `json:"value,omitempty"`
}
example.B = Bool{N: true, B: nil}
output, err := json.Marshal(example)
if err != nil {
panic(err)
}
fmt.Println(string(output))
}如果希望在Bool的值为特定值时完全省略该字段,则必须在包含的结构上定义MarshalJSON方法,以便在需要时可以正确省略该字段。
https://stackoverflow.com/questions/61135810
复制相似问题