误解如何使用 MarshalJSON

我有一个相当不寻常的情况。我希望 MarshalJSON 有条件地省略一个结构字段。在下面的示例中,想法是省略B Bool字段 if的输出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))

}

根据文档:


“omitempty”选项指定如果字段具有空值(定义为 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},那么它会打印结果,但该字段仍然没有被省略,尽管"false"从Bool.MarshalJSON. 我究竟做错了什么?具有满足Marshaler接口的类型的值是否有效地忽略了省略标记条目?


拉莫斯之舞
浏览 156回答 1
1回答

饮歌长啸

 if b.Value == b.Undefined {        return []byte{}, nil产生无效的 JSON:它返回 0 个字节。您的MarshalJSON方法必须返回有效的 JSON,这意味着它必须返回something。如果您的目标是完全忽略该字段,则在未设置时,请使用指针,并且不要设置它: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在包含结构上定义您的方法,以便它可以在需要时正确省略该字段。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go