[英]Golang / Go - How to marshal struct to null if it has no fields?
我知道这可能看起来是一个常见的问题,但请告诉我......
我有一个结构,其中一个字段类型等于另一个结构的字段类型:
type Developer struct {
Name string `json:"name,omitempty"`
ProjectRef *Ref `json:"project,omitempty"`
}
type Ref struct {
ID string `json:"id,omitempty"`
}
在我的实施中,我无法保证是否存在或不会成为开发人员的 ProjectRef。 如果我创建一个ID为null的Ref,即一个空字符串,那么这个字段从Ref中被省略了,但是,即使此时我的Ref没有字段,为什么它没有被省略为空?
我想克服这个问题的一种方法是使用一堆条件语句,但我不想让自己这样做,因为我有很多情况需要这个功能。
完整演示代码:
package main
import (
"encoding/json"
"fmt"
)
type Developer struct {
Name string `json:"name,omitempty"`
ProjectRef *Ref `json:"project,omitempty"`
}
type Ref struct {
ID string `json:"id,omitempty"`
}
func main() {
developer := &Developer{
Name: "Charlie",
ProjectRef: &Ref{ID: ""},
}
jsonBytes, err := json.Marshal(developer)
if err != nil {
panic(err)
}
fmt.Println(string(jsonBytes))
// {"name":"Charlie","project":{}}
}
游乐场链接: https://go.dev/play/p/D2edbrACXY2
先感谢您
即使结构的所有字段都包含零值,也会对结构进行编组。
一种方法是保留Developer.ProjectRef
字段nil
,并删除omitempty
属性。 这样它将被编组为 JSON null
值:
type Developer struct {
Name string `json:"name,omitempty"`
ProjectRef *Ref `json:"project"`
}
测试它:
developer := &Developer{
Name: "Charlie",
}
jsonBytes, err := json.Marshal(developer)
if err != nil {
panic(err)
}
fmt.Println(string(jsonBytes))
developer.ProjectRef = &Ref{ID: "abc"}
jsonBytes, err = json.Marshal(developer)
if err != nil {
panic(err)
}
fmt.Println(string(jsonBytes))
Output(在Go 游乐场试试):
{"name":"Charlie","project":null}
{"name":"Charlie","project":{"id":"abc"}}
如果您始终希望Developer.ProjectRef
成为非nil
指针,则为Ref
编写自定义JSON 编组器,如果 ID 为空,它可以编组 JSON null
值:
func (r *Ref) MarshalJSON() ([]byte, error) {
if r.ID == "" {
return []byte("null"), nil
}
type ref2 Ref
return json.Marshal((*ref2)(r))
}
测试它:
developer := &Developer{
Name: "Charlie",
ProjectRef: &Ref{ID: ""},
}
jsonBytes, err := json.Marshal(developer)
if err != nil {
panic(err)
}
fmt.Println(string(jsonBytes))
developer.ProjectRef.ID = "abc"
jsonBytes, err = json.Marshal(developer)
if err != nil {
panic(err)
}
fmt.Println(string(jsonBytes))
Output(在Go 游乐场试试):
{"name":"Charlie","project":null}
{"name":"Charlie","project":{"id":"abc"}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.