go - 如何处理结构类型中的零结构变量
问题描述
我需要编组/解组 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"
}
}
如果我遵循 struct 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 传递给 Payload 结构。
解决方案
json.Marshaler接口可以实现自定义 JSON 编码,json.Unmarshaler 接口用于解码(留给读者练习):
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
需要ad-hoc_payload
类型来防止递归。如果有人写return json.Marshal(p)
,json 包会MarshalJSON
再次调用,因为 p 是类型payload
,并且payload
实现了 json.Marshaler。
该类型与json.Marshaler_payload
具有相同的底层类型payload
但没有实现(详见类型定义),因此使用 json 包的标准规则进行编码;payload
如果payload
没有实现 json.Marshaler ,它会产生与编码类型值完全相同的输出。
推荐阅读
- google-apps-script - 使用脚本从 Google 表单打开一个新的 Google 电子表格文件
- azure - 如何更改现有 Azure 应用程序网关的 VNet 和子网?
- visual-studio - 将 Unity 应用程序提交到 Windows 商店
- rest - HATEOAS 不会增加 HTTP 请求吗?
- list - 如何在列表中搜索特定元素
- javascript - 如何使用 Eventbrite Api 查询特定城市特定日期的所有事件?
- android - 为什么真实设备上的xamarin android应用程序总是抛出错误但在模拟器上工作
- python - python 比较 datatime.time 和 datetime.timedelta
- c++ - Boost:如何在 C POSIX 正则表达式接口中使用 \\+
- r - 从 dgCMatrix/dgRMatrix 转换为 scipy 稀疏矩阵