我的情况很不正常。我希望MarshalJSON有条件地省略结构字段。在下面的示例中,想法是如果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))
}
Playground link
根据文档:
我返回一个空 byte slice ,这将导致错误:
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}
,那么它将打印结果,但是尽管从"false"
返回了Bool.MarshalJSON
,但该字段仍然没有被省略。我究竟做错了什么?类型满足Marshaler
接口(interface)的值是否有效地忽略了omtempty标签条目? 最佳答案
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
的值为特定值时完全忽略该字段,则必须在包含的struct上定义MarshalJSON
方法,以便在需要时可以正确忽略该字段。关于json - 误解了如何使用MarshalJSON,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61135810/