Golang 的 “omitempty” 關(guān)鍵字詳解
?json和struct轉(zhuǎn)換簡單介紹
熟悉 Golang 的朋友對于 json 和 struct 之間的轉(zhuǎn)換一定不陌生,為了將代碼中的結(jié)構(gòu)體與 json 數(shù)據(jù)解耦,通常我們會在結(jié)構(gòu)體的 field 類型后加上解釋說明,注意:「結(jié)構(gòu)體的屬性首字母必須大寫,否則json解析會不生效」。
結(jié)構(gòu)體只初始化部分變量?
接下來我們看另外一種情況:
如果我們在結(jié)構(gòu)體初始化的時候只初始化了其中一個字段Name,那么理論上來說返回的json應(yīng)該是。
但是我們實際運行一下返回的結(jié)果卻是。
這明顯是不符合我們的預(yù)期的,因為Age字段是我們不需要的。
如何解決?
接下來就輪到咱們今天的主角登場了,解決方式很簡單,在后面加上「omitempty」即可。
結(jié)構(gòu)體的特殊情況?
我們再來看下面的這個例子:
我們對結(jié)構(gòu)體「Person定義了omitempty」,按理說我們在初始化的時候并「沒有初始化結(jié)構(gòu)體的任何屬性」,所以轉(zhuǎn)換成json之后的打印結(jié)果應(yīng)該是只有{"Num":5}的,但是我們實際運行之后發(fā)現(xiàn)打印的結(jié)果卻是。
為什么「omitempty對于結(jié)構(gòu)體類型不生效」了呢?「這是因為結(jié)構(gòu)體(上面例子的Person)不知道空值是什么,GO只知道簡單結(jié)構(gòu)體例如int,string,pointer 這種類型的空值」,為了不顯示我們沒有提供值的自定義結(jié)構(gòu)體,我們可以使用「結(jié)構(gòu)體指針」。
為什么用指針類型就可以解決這個問題?因為「指針是基本類型,Golang知道他的空值是啥」,所以就直接賦值為nil(指針類型的空值)。
omitempty的一個大坑?
我們接下來還是看例子:
按照咱們的預(yù)期,應(yīng)該給輸出。
對不對,但是咱們實際運行以后輸出的卻是。
這明顯有問題啊,咱們需要的是輸出的json字段,是必須有age,而且值是0,現(xiàn)在什么都沒輸出明顯是有問題的?!敢驗镚olang把0當(dāng)成了零值,所以跟沒有賦值是一樣的」如果想解決這種問題一種方法是「使用int指針」,因為int指針的空值為nil,當(dāng)我想輸出0的時候,我傳進去地址,地址肯定不是空值nil,這樣肯定會顯示出來0。
總結(jié)?
omitempty只是在把結(jié)構(gòu)體轉(zhuǎn)換成json的過程中,「只會影響json轉(zhuǎn)換后的結(jié)果,并不是影響結(jié)構(gòu)體本身」,所以結(jié)構(gòu)體的任何屬性設(shè)置了omitempty之后,都不影響其正常使用。
omitempty的作用簡單來說就是在「結(jié)構(gòu)體轉(zhuǎn)換json的過程中」,「把沒有賦值的結(jié)構(gòu)體屬性不在json中輸出而已」。
omitempty只支持「簡單的數(shù)據(jù)類型」,對「結(jié)構(gòu)體的數(shù)據(jù)類型是不生效」的,如果需要生效,只能用「結(jié)構(gòu)體指針」。
omitempty分不清楚「0值,""值和未賦值」,「如果給某個屬性賦值0或者"",并且想輸出,只能用指針類型」。