0%

golang 方法作为字段转JSON

假设有一个结构体来表示用户信息:

1
2
3
4
5
6
type User struct {
Name string `json:"name"`
Sex string `json:"sex"`
Age int `json:"age"`
Vip bool `json:"vip"`
}

然后有个需求是展示给用户的名称要根据用户的性别VIP来生成,比如说:

  • 如果用户是 VIP,那么展示 尊贵的 + 名字 + 先生/女士
  • 如果用户不是 VIP,那么展示 名字 + 先生/女士

这个时候一般会有个做法,在结构体中加一个字段:

1
2
3
4
5
6
7
8
9
10
11
12
type User struct {
Name string `json:"name"`
Sex string `json:"sex"`
Age int `json:"age"`
Vip bool `json:"vip"`
DisplayName string `json:"display_name"`
}

// 实现一个方法来设置 DisplayName 字段
func (u *User) SetDisplayName() {

}

然后在每次更新NameSexVip的时候调用SetDisplayName方法来更新DisplayName字段,或者在序列化的时候调用SetDisplayName方法来更新DisplayName字段,这样做是没问题的,但是非常的不利于维护,要到处硬编码调用SetDisplayName方法,非常容易遗漏,那么有没有什么优雅的方式来解决这个问题呢?答案是有的,下面来介绍一下。

方法作为字段转JSON

golang在做JSON序列化的时候,会调用结构体的MarshalJSON方法,可以利用这个特性来解决这个问题,也就是自定义序列化实现,在每次序列化的时候动态计算DisplayName字段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 实现一个方法来返回 DisplayName 字段
func (u *User) DisplayName() string {

}

// 实现 MarshalJSON 方法
func (u *User) MarshalJSON() ([]byte, error) {
// 这里要用一个新的结构体来存储原始的 User 结构体,不然会造成递归调用 DisplayName 方法
type rawUser User
return json.Marshal(struct {
rawUser
DisplayName string `json:"display_name"`
}{
rawUser: rawUser(*u),
DisplayName: u.DisplayName(),
})
}

这样就可以在序列化的时候动态计算DisplayName字段了。

当然上面的示例只是抛砖引玉,可以根据实际业务来使用,比如说直接交给前端来处理DisplayName字段逻辑,本文主要是记录一下golang中方法作为字段转JSON的方法。


我是MonkeyWie,欢迎扫码👇👇关注!不定期在公众号中分享JAVAGolang前端dockerk8s等干货知识。

如果觉得本文对您有帮助,可以请我喝一杯咖啡☕