Golang / Go - 如果结构没有字段,如何将其编组为 null?
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":{}}
}
Link 去游乐场:https://go.dev/play/p/D2edbrACXY2
提前致谢
即使结构的所有字段都包含 zero values.
,结构也会被编组
一种方法是保留 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))
输出(在 Go Playground 上尝试):
{"name":"Charlie","project":null}
{"name":"Charlie","project":{"id":"abc"}}
如果你总是希望 Developer.ProjectRef
成为一个非 nil
指针,那么为 Ref
写一个自定义 JSON marshaler,它可以编组 JSON null
ID为空时的值:
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))
输出(在 Go Playground 上尝试):
{"name":"Charlie","project":null}
{"name":"Charlie","project":{"id":"abc"}}
我知道这可能是一个常见的问题,但请告诉我...
我有一个结构,其中一个字段类型与另一个结构的字段类型相同:
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":{}}
}
Link 去游乐场:https://go.dev/play/p/D2edbrACXY2
提前致谢
即使结构的所有字段都包含 zero values.
,结构也会被编组一种方法是保留 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))
输出(在 Go Playground 上尝试):
{"name":"Charlie","project":null}
{"name":"Charlie","project":{"id":"abc"}}
如果你总是希望 Developer.ProjectRef
成为一个非 nil
指针,那么为 Ref
写一个自定义 JSON marshaler,它可以编组 JSON null
ID为空时的值:
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))
输出(在 Go Playground 上尝试):
{"name":"Charlie","project":null}
{"name":"Charlie","project":{"id":"abc"}}