首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用MarshalJSON的误区

如何使用MarshalJSON的误区
EN

Stack Overflow用户
提问于 2020-04-10 07:31:30
回答 1查看 399关注 0票数 0

我有个很不寻常的情况。我希望MarshalJSON有条件地省略一个struct字段。在下面的示例中,我们的想法是省略B Bool字段的输出,如果是B.Value == B.Undefined

代码语言:javascript
复制
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接口值以及任何空数组、切片、映射或字符串,则应从编码中省略该字段。

我返回一个空字节片,这将导致一个错误:

代码语言:javascript
复制
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接口的值是否有效地忽略了省略标记条目?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-10 07:36:53

代码语言:javascript
复制
 if b.Value == b.Undefined {
        return []byte{}, nil

生成无效的JSON:它返回0字节。您的MarshalJSON方法必须返回有效的JSON,这意味着它必须返回一些东西。

如果您的目标是完全省略该字段,则在未设置该字段时,请使用指针,不要设置:

代码语言:javascript
复制
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方法,以便在需要时可以正确省略该字段。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61135810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档