在完成大项目的过程中,避免不了会在json和struct之间频繁转换,这里感谢网上的各种转换工具,省去了繁琐的构造结构体的过程。为了将代码中的结构体与json数据解耦,通常我们会在结构体的field类型后加上解释说明。例如:
{
"status_code": 0,
"status_msg": "string",
"user_id": 0,
"token": "string"
}
对应的结构体可以为
type Response struct {
StatusCode int `json:"status_code"`
StatusMsg string `json:"status_msg"`
UserID int `json:"user_id"`
Token string `json:"token"`
}
在编写业务逻辑的过程中,会发现有时候并不需要传递结构体中的某些字段,但是返回的json数据中该字段依然存在,这时候我们就需要使用omitempty关键字,这里我们不想UserID和Token字段存在默认值,可以这样定义结构体
type Response struct {
StatusCode int `json:"status_code"`
StatusMsg string `json:"status_msg"`
UserID int `json:"user_id,omitempty"`
Token string `json:"token,omitempty"`
}
omitempty使用存在的问题
嵌套结构体
假定有如下结构体
type User struct {
UserID int `json:"user_id"`
}
type Response struct {
StatusCode int `json:"status_code"`
User User `json:"user,omitempty"`
}
在使用Response时我们想主动忽略其中的User字段,但是运行会发现这样是行不通的,User字段无论如何都不会被忽略。
正确做法是将嵌套结构体定义为指针类型,当传入为nil时,不会为其分配默认值。
//正确定义方法
type Response struct {
StatusCode int `json:"status_code"`
User *User `json:"user,omitempty"`
}
字段默认值
还是回到最初的结构体
type Response struct {
StatusCode int `json:"status_code"`
StatusMsg string `json:"status_msg"`
UserID int `json:"user_id,omitempty"`
Token string `json:"token,omitempty"`
}
假如我们想定义一个UserID为0的结构体,将其转换为json数据会发现不存在user_id字段。这和我们刚刚为了解决嵌套结构体问题时的思路很像,指针的空值是nil,当对应字段值为nil时也不会被解析,所以可以总结一下,当使用omitempty关键字时,GoLang会忽略结构体中值为空或者为默认值的字段。
想要解决默认值问题,还是得采用指针的方法,因为指针的默认值nil一般不会采用,修改后的结构体如下
type Response struct {
StatusCode int `json:"status_code"`
StatusMsg string `json:"status_msg"`
UserID *int `json:"user_id,omitempty"`
Token string `json:"token,omitempty"`
}