我有一个包含 2 个播放器的结构表,但在发送 JSON 时我需要忽略结构 Player
中的一些属性。
我可以使用 json:"-"
,但是该属性将始终被忽略,并且只有在发送 Table 结构时我才需要忽略它。当我在代码的其他部分发送 Player
时,我需要这些属性。
我有:
type Player struct {
Id Int64 `json:"id"`
Username string `json:"username,omitempty"`
Password string `json:"-,omitempty"`
Email string `json:"email,omitempty"`
Birthdate time.Time `json:"birthdate,omitempty"`
Avatar string `json:avatar,omitempty"`
}
type Table struct {
Id int `json:"id"`
PlayerTop Player `json:"playerTop"`
PlayerBottom Player `json:"playerBottom"`
}
我需要:
{
"Table": {
"id": 1,
"playerBottom": {
"id": 1,
"username": "peter",
"avatar": "avatar.png"
},
"playerTop": {
"id": 1,
"username": "peter",
"avatar": "avatar.png"
}
}
}
玩家来自数据库,所以属性不为空。
a) 我可以这样做:
myTable = new(Table)
myTable.PlayerBottom.Email = ""
myTable.PlayerBottom.Birthdate = ""
myTable.PlayerTop.Email = ""
myTable.PlayerTop.Birthdate = ""
所以这些属性将在 JSON 中被忽略,感谢 json:"omitempty"
,但这是个坏主意。
b) 我可以使用别名结构之类的东西,但是 Table
期望 PlayerBottom
是 Player
类型而不是 PlayerAlias
,但我不知道如何实现它:
type PlayerAlias struct {
Id Int64 `json:"id"`
Username string `json:"username,omitempty"`
Avatar string `json:avatar,omitempty"`
}
c) 在发送之前,我尝试动态添加 json:"-"
到我不想要的 JSON 属性,但结果一团糟。
最佳答案
您可以为 Table
类型创建自定义 Marshaler
。这是您必须实现的接口(interface):
https://golang.org/pkg/encoding/json/#Marshaler
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
然后您将从 Player
中删除 -
标记(因为当您在别处编码它时您需要保留字段)并且仅在自定义 中忽略它
方法。Table
的 >MarshalJSON
这是一个简单的(不相关的)示例,它为一种类型实现自定义编码(marshal)处理,以十六进制编码其中一个字段:
type Account struct {
Id int32
Name string
}
func (a Account) MarshalJSON() ([]byte, error) {
m := map[string]string{
"id": fmt.Sprintf("0x%08x", a.Id),
"name": a.Name,
}
return json.Marshal(m)
}
func main() {
joe := Account{Id: 123, Name: "Joe"}
fmt.Println(joe)
s, _ := json.Marshal(joe)
fmt.Println(string(s))
}
正如您在此处看到的,通过构建一个只包含您需要的字段的 map
并将其传递给 json.Marshal
,可以很容易地完成这种编码(marshal)处理。对于您的 Table
和 Player
,这只会产生几行简单的代码。恕我直言,这样做比修改类型并使用嵌入/别名使它们复杂化更好,只是为了 JSON 编码。
关于json - 隐藏 JSON 中的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54751615/