詳解Golang如何優(yōu)雅判斷interface是否為nil
背景
很久之前發(fā)過(guò)一篇文章:《10個(gè)令人驚嘆的Go語(yǔ)言技巧,讓你的代碼更加優(yōu)雅》,這篇文章中第八點(diǎn)有一處錯(cuò)誤的地方被認(rèn)真的讀者發(fā)現(xiàn)了:
于是我有空之后,立馬重新看了那篇文章的內(nèi)容,確實(shí)是存在讀者所說(shuō)的問(wèn)題。
問(wèn)題
問(wèn)題就在于下面這句話,文章也是有列出的:
即使接口持有的值為 nil
,也不意味著接口本身為 nil
。
但是在執(zhí)行以下語(yǔ)句的時(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
方法。
那么問(wèn)題就很好解決了。
解決方式
我們?cè)趫?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
。
下面我們使用幾種常見(jiàn)的數(shù)據(jù)類型來(lái)進(jìn)行測(cè)試:
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)體
來(lái)測(cè)試此 IsNil
方法。運(yùn)行程序輸出為:
int IsNil: false
intPtr IsNil: true
slice IsNil: false
map IsNil: false
interface IsNil: true
structPtr IsNil: true
從測(cè)試結(jié)果來(lái)看,目前是符合我們對(duì)此方法的定位的。
到此這篇關(guān)于詳解Golang如何優(yōu)雅判斷interface是否為nil的文章就介紹到這了,更多相關(guān)Go判斷interface是否為nil內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
我為什么喜歡Go語(yǔ)言(簡(jiǎn)潔的Go語(yǔ)言)
從2000年至今,也寫(xiě)了11年代碼了,期間用過(guò)VB、Delphi、C#、C++、Ruby、Python,一直在尋找一門(mén)符合自己心意和理念的語(yǔ)言。我很在意寫(xiě)代碼時(shí)的手感和執(zhí)行的效率,所以在Go出現(xiàn)之前一直沒(méi)有找到2014-10-10Go語(yǔ)言對(duì)JSON進(jìn)行編碼和解碼的方法
這篇文章主要介紹了Go語(yǔ)言對(duì)JSON進(jìn)行編碼和解碼的方法,涉及Go語(yǔ)言操作json的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02Go使用defer函數(shù)要注意的幾個(gè)點(diǎn)
這篇文章主要介紹了Go使用defer函數(shù)要注意的幾個(gè)點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12golang連接MongoDB數(shù)據(jù)庫(kù)及數(shù)據(jù)庫(kù)操作指南
MongoDB是Nosql中常用的一種數(shù)據(jù)庫(kù),下面這篇文章主要給大家介紹了關(guān)于golang連接MongoDB數(shù)據(jù)庫(kù)及數(shù)據(jù)庫(kù)操作的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09Go語(yǔ)言實(shí)現(xiàn)支付寶支付與退款詳解
本文詳細(xì)介紹使用Go語(yǔ)言對(duì)接支付寶支付與退款功能的步驟和注意事項(xiàng),包括PC端、WAP端和Android端支付實(shí)現(xiàn),以及退款功能的代碼實(shí)現(xiàn),介紹了GoPay庫(kù)的使用,幫助開(kāi)發(fā)者快速集成支付寶支付到應(yīng)用中2024-10-10Golang加權(quán)輪詢負(fù)載均衡的實(shí)現(xiàn)
負(fù)載均衡器在向后端服務(wù)分發(fā)流量負(fù)載時(shí)可以使用幾種策略。本文主要介紹了Golang加權(quán)輪詢負(fù)載均衡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06