Go語言omitempty選項的實現(xiàn)
在使用Golang的時候,不免會使用Json和結構體的相互轉換,這時候常用的就是 json.Marshal 和 json.Unmarshal 兩個函數(shù)。這時候在定義json結構體的時候,我們會用到 omitempty 這個字段,這個字段作用就是 空值省略,看似簡單,但是卻有很多小坑,這篇文章帶你稍微研究一下他的用途和功能。
omit:
v. 刪除; 忽略; 漏掉; 遺漏; 不做; 未能做;
adj. 省略了的;省去的;
基本用法
當我們設置json的struct的時候,會定義每個字段對一個json的格式,比如定義一個dog 結構體:
type Dog struct { Name string Weight int }
現(xiàn)在我們對他進行初始化,將其編碼為JSON格式:
func main() { d := Dog{ Name: "小黑", Weight: 20, } marshalDog, err := json.Marshal(d) if err != nil { fmt.Println(err.Error()) } fmt.Println(string(marshalDog)) }
則輸出的結果為:
{"Name":"小黑","Weight":20}
現(xiàn)在假如有一個結構體變量我們沒初始化,那么結果可能也會跟我們預期的不太一樣:
d := Dog{ Name: "小黑", }
輸出的結果為:
{"Name":"小黑","Weight":0}
很明顯,狗的weight是未知,而不是0,并不是我們想要的結果,我們更想要的結果是:
{"Name":"小黑"}
為了實現(xiàn)這樣的目的,我們這時候應該使用 omitempty 選項來幫我們實現(xiàn),當我們在Dog結構體加上這個tag的時候:
type Dog struct { Name string Weight int `json:",omitempty"` }
此時,輸出結果為:
{"Name":"小黑"}
不能單純使用omitempty
當結構體相互嵌套的時候,那么omitempty就可能出現(xiàn)問題,比如:
type Variety struct { ?? ?Color ? ?string ?? ?Category string } type Dog struct { ?? ?Name ? ?string ?? ?Weight ?int ? ? `json:",omitempty"` ?? ?Variety Variety `json:",omitempty"` } func main() { ?? ?d := Dog{ ?? ??? ?Name: "小黑", ?? ?} ?? ?marshalDog, err := json.Marshal(d) ?? ?if err != nil { ?? ??? ?fmt.Println(err.Error()) ?? ?} ?? ?fmt.Println(string(marshalDog)) }
輸出結果為:
{"Name":"小黑","Variety":{"Color":"","Category":""}}
omitempty 為什么對嵌套結構體不生效呢?這是因為GO只知道簡單結構體例如int,string,pointer 這種類型的空值,不知道Variety類型的空值是什么,為了不顯示我們沒有提供值的自定義結構體,我們可以使用結構體指針:
type Dog struct { Name string Weight int `json:",omitempty"` Variety *Variety `json:",omitempty"` }
運行結果為:
{"Name":"小黑"}
但是如果給出下面情況的賦值:
d := Dog{ Name: "小黑", Variety: &Variety{Color: "black"}, }
運行結果為:
{"Name":"小黑","Variety":{"Color":"black","Category":""}}
可以看到,omitempty只對*Variety生效。所以想要嵌套結構體里面的字段也能有空值省略的效果,就要在定義嵌套的結構體的時候,對里面的每個字段都要加上omitempty選項。如下所示:
type Variety struct { Color string `json:",omitempty"` Category string `json:",omitempty"` }
運行結果如下:
{"Name":"小黑","Variety":{"Color":"black"}}
剩下的最后一個坑就是:如果想要某個值就是為空(有實際意義),也就是說當一個空值有實際意義的時候就顯示,沒有實際意義(當時還不知道其值)的時候就不顯示,這樣的需求應該怎么做?如果還是向上面那樣,當我們需要Category為空的時候(Category:“”),最后會發(fā)現(xiàn)omitempty選項會把這個空值字段省略。正確的做法是使用指針來定義其變量。最后代碼如下:
package main import ( ?? ?"encoding/json" ?? ?"fmt" ) type Variety struct { ?? ?Color ? ?*string `json:",omitempty"` ?? ?Category *string `json:",omitempty"`//一定要是*string類型 } type Dog struct { ?? ?Name ? ?string ?? ?Weight ?int ? ? ?`json:",omitempty"` ?? ?Variety *Variety `json:",omitempty"` } func main() { ?? ?color := "black" ? ? //此處的空值有實際意義 ?? ?category := "" ?? ?d := Dog{ ?? ??? ?Name: ? ?"小黑", ?? ??? ?Variety: &Variety{Color: &color, Category: &category}, ?? ?} ?? ?marshalDog, err := json.Marshal(d) ?? ?if err != nil { ?? ??? ?fmt.Println(err.Error()) ?? ?} ?? ?fmt.Println(string(marshalDog)) }
運行結果如下:
{"Name":"小黑","Variety":{"Color":"black","Category":""}}
到此這篇關于Go語言omitempty選項的實現(xiàn)的文章就介紹到這了,更多相關Go語言omitempty選項內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
golang?sync.Cond同步機制運用及實現(xiàn)
在?Go?里有專門為同步通信而生的?channel,所以較少看到?sync.Cond?的使用,不過它也是并發(fā)控制手段里的一種,今天我們就來認識下它的相關實現(xiàn),加深對同步機制的運用2023-09-09利用go-zero在Go中快速實現(xiàn)JWT認證的步驟詳解
這篇文章主要介紹了如何利用go-zero在Go中快速實現(xiàn)JWT認證,本文分步驟通過實例圖文相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2020-10-10