詳解Golang如何優(yōu)雅判斷interface是否為nil
背景
很久之前發(fā)過一篇文章:《10個(gè)令人驚嘆的Go語言技巧,讓你的代碼更加優(yōu)雅》,這篇文章中第八點(diǎn)有一處錯(cuò)誤的地方被認(rèn)真的讀者發(fā)現(xiàn)了:
于是我有空之后,立馬重新看了那篇文章的內(nèi)容,確實(shí)是存在讀者所說的問題。
問題
問題就在于下面這句話,文章也是有列出的:
即使接口持有的值為 nil
,也不意味著接口本身為 nil
。
但是在執(zhí)行以下語句的時(shí)候,是有可能報(bào) panic
的:
return reflect.ValueOf(x).IsNil()
而輸出也是非常明顯的指出錯(cuò)誤:
panic: reflect: call of reflect.Value.IsNil on int Value
因?yàn)椴豢?nbsp;nil
的 interface
是不能使用 reflect.Value.IsNil
方法。
那么問題就很好解決了。
解決方式
我們在執(zhí)行 reflect.Value.IsNil
方法之前,進(jìn)行一次判斷是否為指針即可:
func IsNil(x interface{}) bool { if x == nil { return true } rv := reflect.ValueOf(x) return rv.Kind() == reflect.Ptr && rv.IsNil() }
重點(diǎn)在于 rv.Kind() == reflect.Ptr && rv.IsNil()
這段代碼。
這段代碼的作用:
- 判斷
x
的類型是否為指針。 - 判斷
x
的值是否真的為nil
。
下面我們使用幾種常見的數(shù)據(jù)類型來進(jìn)行測試:
func IsNil(x interface{}) bool { if x == nil { return true } rv := reflect.ValueOf(x) return rv.Kind() == reflect.Ptr && rv.IsNil() } func main() { fmt.Printf("int IsNil: %t\n", IsNil(returnInt())) fmt.Printf("intPtr IsNil: %t\n", IsNil(returnIntPtr())) fmt.Printf("slice IsNil: %t\n", IsNil(returnSlice())) fmt.Printf("map IsNil: %t\n", IsNil(returnMap())) fmt.Printf("interface IsNil: %t\n", IsNil(returnInterface())) fmt.Printf("structPtr IsNil: %t\n", IsNil(returnStructPtr())) } func returnInt() interface{} { var value int return value } func returnIntPtr() interface{} { var value *int return value } func returnSlice() interface{} { var value []string return value } func returnMap() interface{} { var value map[string]struct{} return value } func returnInterface() interface{} { var value interface{} return value } type People struct { Name string } func returnStructPtr() interface{} { var value *People return value }
我們先后使用了 int
、*int
、slice
、map
、interface{}
、自定義結(jié)構(gòu)體
來測試此 IsNil
方法。運(yùn)行程序輸出為:
int IsNil: false
intPtr IsNil: true
slice IsNil: false
map IsNil: false
interface IsNil: true
structPtr IsNil: true
從測試結(jié)果來看,目前是符合我們對此方法的定位的。
到此這篇關(guān)于詳解Golang如何優(yōu)雅判斷interface是否為nil的文章就介紹到這了,更多相關(guān)Go判斷interface是否為nil內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go使用defer函數(shù)要注意的幾個(gè)點(diǎn)
這篇文章主要介紹了Go使用defer函數(shù)要注意的幾個(gè)點(diǎn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12golang連接MongoDB數(shù)據(jù)庫及數(shù)據(jù)庫操作指南
MongoDB是Nosql中常用的一種數(shù)據(jù)庫,下面這篇文章主要給大家介紹了關(guān)于golang連接MongoDB數(shù)據(jù)庫及數(shù)據(jù)庫操作的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09Golang加權(quán)輪詢負(fù)載均衡的實(shí)現(xiàn)
負(fù)載均衡器在向后端服務(wù)分發(fā)流量負(fù)載時(shí)可以使用幾種策略。本文主要介紹了Golang加權(quán)輪詢負(fù)載均衡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06