我正在尝试为可能的nil
数据库类型编写自定义封送程序。它的结构与sql.NullFloat64
类型完全相同:
type NullFloat64 sql.NullFloat64
func (ni *NullFloat64) MarshalJSON() ([]byte, error) {
if !ni.Valid {
return []byte("null"), nil
}
return json.Marshal(ni.Float64)
}
哪个是要编组的较大struct
的一部分:
type Data struct {
X time.Time `json:"x"`
Y float32 `json:"y"`
Stderr NullFloat64 `json:"stderr"`
}
如果我尝试json.Marshal()
这个struct
,它可以正常工作,创建:
{"x":"2017-01-12T23:36:12-05:00","y":4,"stderr":null}
如果值为null
,我想完全省略JSON密钥。我将json:"stderr,omitempty"
添加到Data
。
根据建议here,我尝试从nil
返回MarshalJSON
值,但得到了:
json: error calling MarshalJSON for type common.NullFloat64: unexpected end of JSON input
我还尝试将Data
更新为:
type Data struct {
X time.Time `json:"x"`
Y float32 `json:"y"`
Stderr *NullFloat64 `json:"stderr,omitempty"`
}
编组:
Data {
X: datetime,
Y: value,
Stderr: &stderr,
}
但是,像以前一样从nil
返回MarshalJSON
时遇到同样的错误。
那么,我如何为自定义类型实现MarshalJSON
并在编组时省略密钥?
谢谢您的帮助!
答案 0 :(得分:0)
如果您创建的类型如此:
Data {
X: datetime,
Y: value,
Stderr: nil,
}
omitempty
将启动并“做正确的事”。可悲的是,我很确定这对你没用。
如果您确实要省略基于字段和内部的状态,则需要在结构上实现json.Marshaller
,而不是其子项。最简单的方法如下:
func (d Data) MarshalJSON() ([]byte, error) {
if !d.Stderr.Valid {
return json.Marshal(Data{d.X, d.Y, nil})
}
return json.Marshal(d)
}