Golang中omitempty關鍵字的具體實現

2023-03-19 02:05:37 字數 2011 閱讀 6319

目錄

熟悉 golang 的朋友對程式設計客棧於 json 和 struct 之間的轉換一定不陌生,為了將**中的結構體與 json 資料解耦,通常我們會在結構體的 field 型別後加上解釋說明,例如在表示一個地址的時候, json 資料如下所示

與之相對應的 golang 結構體表示可能是這個樣子的

type address struct

這樣無論**中的變數如何改變,我們都能成功將 json 資料解析出來,獲得正確的街道,城市等資訊,到目前為止一切正常。但如果我們想要將地址結構體恢復成 json 格式時,問題就來了。比方說我們用下面這段**讀取了地址 json ,然後根據業務邏輯處理了之後恢復成正常的 json 列印出來

func main() `

addr := new(address)

json.unmarshal(byte(data), &addr)

// 處理了一番 addr 變數...

addressbytes, _ := json.marshalindent(addr, "", " ")

fmt.printf("%s\n", string(asuvthoddressbytes))

}這段**的輸出是

多了一行 "suite": "", ,而這則資訊在原本的 json 資料中是沒有的(在美國的地址中,如果不是群租公寓或者共享辦公樓, suite 這一條不存在很正常,人們直接用街道門牌號來表示地址就足夠了),但我們更希望的是,在一個地址有 suite 號碼的時候輸出,不存在 suite 的時候就不輸出,幸運的是,我們可以在 golang 的結構體定義中新增 omitempty 關鍵字,來表示這條資訊如果沒有提供,在序列化成 json 的時候就不要包含其預設值。稍作修改,地址結構體就變成了

type address struct

重新執行,即可得到正確的結果。

帶來方便的同時,使用 omitempty 也有些小陷阱,一個是該關鍵字無法忽略掉巢狀結構體。還是拿地址型別說事,這回我們想要往地址結構體中加一個新 field 來表示經緯度,如果沒有缺乏相關的資料,暫時可以忽略。新的 struct 定義如下所示

type address struct

type coordinate struct

讀入原來的地址資料,處理後序列化輸出,我們就會發現即使加上了 omitempty 關鍵字,輸出的 json 還是帶上了一個空的座標資訊

}為了達到我們想要的效果,可以把座標定義為指標型別,這樣 golang 就能知道一個指標的“空值”是多少了,否則面對一個我們自定義的結構, golang 是猜不出我們想要的空值的。於是有了如下的結構體定義

type address struct

type coordinate struct

相應的輸出為

另一個“陷阱”是,對於用 omitempty 定義的 field ,如果給它賦的值恰好等於預設空值的話,在轉為 json 之後也不會輸出這個 field 。比如說上面定義的經緯度座標結構體,如果www.cppcns.com我們將經緯度兩個 field 都加上 omitempty

type coordinate struct

然後我們對非洲幾內亞灣的“原點座標”非常感興趣,於是編寫了如下**

func main() `

c := new(coordinate)

json.unmarshal(byte(cdata), &c)

// 具體處理邏輯...

coordinatebytes, _ := json.marshalindent(c, "", " ")

fmt.printf("%s\n", string(coordinatebytes))

}最終我們得到了一個

這個座標消失不見了!但我們的設想是,如果一個地點沒有經緯度資訊,則懸空,這沒有問題,但對於“原點座標”,我們在確切知道它的經緯度的情況下,(0.0, 0.0)仍然被忽略了。正確的寫法也是將結構體內的定義改為指標

type coordinate struct

這樣空值就從 float64 的 0.0 變為了指標型別的 nil ,我們就能看到正確的經緯度輸出。

golang 中 Template 的使用

專案需求 go 的html template包對html模板提供了豐富的模板語言。主要用於web應用程式,在客戶端的瀏覽中以結構化的方式顯示資料。go提供的模板填充介面,支援各種所以結構。當渲染模板時,要訪問模板中的資料,最前的變數是通過 來訪問。其中花括號中的點 稱為管道和root。模板使用語法 ...

golang中archive tar包詳解

go語言官方標準庫提供tar庫,以方便對tar的操作 一 瞭解tar 什麼是tar?tar是一種打包格式,但不對檔案進行壓縮,所以打包後的文件一般遠遠大於zip和tar.gz,因為不需要壓縮的原因,所以打包的速度是非常快的,打包時cpu佔用率也很低。tar的目的是什麼?方便檔案的管理 幫助理解 就是...

Golang中runtime pprof 的使用

go 中監控 效能的有兩個包 net http pprof runtime pprof 這兩個包都是可以監控 效能的,只不過net http pprof是通過http埠方式暴露出來的,內部封裝的仍然是runtime pprof。1.cpu profiling golang 提供了 pprof 包 r...

golang中goroutine的執行問題記錄

先上 func main wg.add 10 for i 0 i 10 i go func wg.wait 執行結果如下 i 0 i 1 i 2 i 3 i 4 i 5 i 6 i 7 i 8 i 9 我們知道,以上這種寫法是比較規範的對goroutine和channel的使用,由於是順序傳入cha...

golang 中timer,ticker 的使用

寫一個程式,5s,10s後能定時執行一個任務,同時能不停的處理來的訊息。package main import fmt time func main producer produce the messages go func input hello,world t1 time.newtimer ti...

golang中os signal包的使用

os signal包實現對訊號的處理 golang中對訊號的處理主要使用os signal包中的兩個方法 一個是notify方法用來監聽收到的訊號 一個是 stop方法用來取消監聽。func notify c chan os.signal,sig os.signal func notify c ch...

golang中archive tar包用法

tar包實現對tar歸檔檔案的訪問,旨在覆蓋大部分的型別,包括gnu和bsd產生的tars。常量const types typereg 0 普通檔案 typerega 普通檔案 typelink 1 硬連線 typesymlink 2 符號連線,軟連線 typechar 3 字元裝置節點 typeb...

golang中的defer panic使用方法

大家都知道golang裡的panic相當於其他語言裡的throw,而recover相當於其他語言裡的cacth,可是由於golang的recover機制要求必須在defer的函式裡才能執行catchpanic 大概意思如下 func protect g func log.println start ...

vscode中配置golang開發環境

vscode中的terminal中執行go env時,發現gopath gobin與配置的path不一致。原因分析 vscode中的終端使用的bash,所以在配置使用者環境變數時需要編輯 bash profile檔案,而不能是 zshrc檔案。解決辦法就是在bash profile檔案中設定gopa...