如何处理结构类型中的 nil 结构变量



我需要封送/取消封送 json 才能在 golang 中构建。假设结构为

type A struct {
Id string `json:"id"`
Version string `json:"version"`
Actors []actor `json:"actors`
Payload struct {
Name string `json:"name"`
Number string `json:"number"`
}
}
type payload struct {
Name string `json:"name"`
Number string `json:"number"`
}
type actor struct {
Id   string `json:"id"`
Type string `json:"type"`
Role string `json:"role"`
}

参与者或有效载荷可能为空。也许 json

{
"id": "78a07cea-be2b-499c-b82b-e4f510260484",
"version": "1.0.0",
"actors": [
{
"id": "1234567",
"type": "XXX",
"role": "111"
},
{
"id": "7654321",
"type": "YYY",
"role": "222"
}
],
"payload": ""
}

{
"id": "78a07cea-be2b-499c-b82b-e4f510260484",
"version": "1.0.0",
"actors": [],
"payload": {
"name": "XXXX",
"number": "1234567"
}
}

如果我遵循结构 A 设计并尝试在有效载荷为空的情况下封送 json,我必须按如下方式初始化

a := A{
Id: "78a07cea-be2b-499c-b82b-e4f510260484",
Version: "1.0.0",
Actors: []actor{
actor{
Id: "1234567",
Type: "XXX",
Role: "111",
},
actor{
Id: "7654321",
Type: "YYY",
Role: "222",
},
},
Payload: payload{},
}

这将导致以下 json 有一个空的有效负载结构

{
"id": "78a07cea-be2b-499c-b82b-e4f510260484",
"version": "1.0.0",
"actors": [
{
"id": "1234567",
"type": "XXX",
"role": "111"
},
{
"id": "7654321",
"type": "YYY",
"role": "222"
}
],
"payload": {
"name":"",
"number":""
}
}

有什么方法可以生成

"有效载荷": ">

而不是空白的有效负载结构?或者这种 json 格式还有其他结构设计吗?顺便说一句,我无法将 nil 传递给有效负载结构。

json。可以实现封送器接口来自定义 JSON 编码和 json。用于解码的解编拆解器接口(留给读者练习):

package main
import (
"encoding/json"
"fmt"
)
type A struct {
Payload payload
}
type payload struct {
Name   string `json:"name"`
Number string `json:"number"`
}
func (p payload) MarshalJSON() ([]byte, error) {
if p.Name == "" && p.Number == "" {
return []byte(`""`), nil
}
type _payload payload // prevent recursion
return json.Marshal(_payload(p))
}
func main() {
var a A
b, _ := json.MarshalIndent(a, "", "  ")
fmt.Println(string(b))
a.Payload.Name = "foo"
b, _ = json.MarshalIndent(a, "", "  ")
fmt.Println(string(b))
}
// Output:
// {
//   "Payload": ""
// }
// {
//   "Payload": {
//     "name": "foo",
//     "number": ""
//   }
// }

在操场上尝试一下:https://play.golang.org/p/9jhSWnKTnTf

需要临时_payload类型来防止递归。如果写return json.Marshal(p),json包会再次调用MarshalJSON,因为p是payload类型,payload实现json。元帅。

_payload类型与payload具有相同的基础类型,但不实现 json。封送处理器(有关详细信息,请参阅类型定义),因此它使用 json 包的标准规则进行编码;它生成的输出与编码类型为payload的值完全相同,如果payload未实现 JSON,则会产生相同的输出。元帅。

检查将omitempty与 json 结构标签一起使用是否有帮助。我认为这将导致"payload": {}而不是"payload": ""

最新更新