繁体   English   中英

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":{}}
}

游乐场链接: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM