一、jsonomitempty簡介
Jsonomitempty是指可以在構建json數據時,自動判斷是否將該欄位加入json字元串中的標誌,如果該欄位的值為空 或者該欄位為零值,則在編碼成json時不會輸出該欄位。(json中沒有顯式表示為null或者””)。
以下為一個簡單的示例:
type Person struct { Name string `json:"name,omitempty"` Age int `json:"age,omitempty"` Gender string `json:"gender,omitempty"` } func main() { person := Person{ Name: "Lily", Gender: "female", } data, err := json.Marshal(person) if err != nil { fmt.Println("json.Marshal error:", err) } fmt.Println(string(data)) }
輸出結果為:
{"name":"Lily","gender":"female"}
可以看到,由於Age欄位為空值,所以在編碼為json字元串時並未加入該欄位。
二、jsonomitempty的使用場景
Jsonomitempty非常適用於那些需要在向前端傳遞數據時,盡量減小json數據大小的情況。比如在微服務中,不少服務需要向前端提供json數據作為返回。在數據中有大量數據為空值的情況下,使用jsonomitempty可以將返回結果中不必要的數據剔除,降低數據傳輸的負擔。
舉個栗子:
type UserInfo struct { UserName string `json:"user_name"` UserId int64 `json:"user_id"` Email string `json:"email,omitempty"` Phone string `json:"phone,omitempty"` Avatar string `json:"avatar,omitempty"` Gender string `json:"gender,omitempty"` } func GetUserInfo(userId int64) UserInfo { userInfo := UserInfo{ UserName: "jack", UserId: userId, } //... 查詢資料庫... return userInfo }
以上代碼演示了一個獲取用戶信息的函數,這個函數從資料庫中查詢用戶信息,並將其組裝成UserInfo對象返回。在返回結果中,由於郵箱、電話、頭像和性別可能為空值,所以我們使用jsonomitempty標記,將這些欄位從json字元串中剔除,如下所示。
假設該用戶userId為1,介面返回結果如下:
{"user_name":"jack","user_id":1}
可以看到,由於郵箱、電話、頭像及性別都為空值,因此在編碼成json字元串時並未加入這些欄位。
三、jsonomitempty的限制
儘管jsonomitempty看起來非常有用,但它並不是萬能的。在使用jsonomitempty時,需要注意以下幾點限制。
1、”omitempty”欄位可能會帶來歧義
在Go中,有些零值不等於空值。如果您的欄位具有零值,並且您使用omitempty標記,則在組合json對象時,該欄位將被視為空。因此,在使用jsonomitempty時,必須協調解決方案,以使一致性得到維護。
以Time類型為例,在默認情況下,它被視為 “非空” 。因此,使用omitempty標記,將清空Time類型的零值。
type StructA struct { Time time.Time `json:"time,omitempty"` } sa := StructA{Time: time.Time{}}
執行結果:
{}
2、Tag中不得使用”omitempty”欄位進行json解碼
您在集合json字元串時使用omitempty。您可以忽略其中某些不是必須的值,但在反序列化JSON時卻無法使用此欄位。在從json字元串構造結構體時,欄位的零值應保留並由程序員手動驗證是否為零值。例如:
type StructB struct { Time time.Time `json:"time,omitempty"` } sbJsonStr := `{"time":"2014-11-12T11:45:30.918Z"}` sbParsed := StructB{} err := json.Unmarshal([]byte(sbJsonStr), &sbParsed) if err != nil { fmt.Println(err) } fmt.Println(sbParsed)
執行結果:
{}
在json.Unmarshal中使用`omitempty`欄位標記,無法正常反序列化json字元串。
3、omitempty會自動忽略零值
如果您希望保留結構的默認值,而不管它是否為空,哪怕是零值您也不要使用omitempty。
type StructC struct { Num int `json:"num,omitempty"` } sc := StructC{} jb, _ := json.Marshal(sc) fmt.Println(string(jb)) // 輸出 {}
如果刪除”omitempty”標記,則輸出為{“num”:0}。
四、總結
在我們的日常開發中,json字元串的交換、以及對不同源代碼的調用,已經成為編寫更好軟體的不可缺少的一部分。這種數據交換可能涉及到客戶端之間的交互,或者是從API向外提供服務。對於此類情況使用jsonomitempty是非常必要的。
通過本文的介紹,相信大家對jsonomitempty有了更深入的理解,並且在日常編碼中也更加熟練掌握它的使用。不管是在Go語言還是其他的編程語言中,jsonomitempty都是一種很實用的編碼和解碼技巧,值得我們掌握。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/286881.html