詳解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)文章
golang hack插件開(kāi)發(fā)動(dòng)態(tài)鏈接庫(kù)實(shí)例探究
這篇文章主要為大家介紹了golang hack插件開(kāi)發(fā)動(dòng)態(tài)鏈接庫(kù)實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Golang使用archive/zip包實(shí)現(xiàn)ZIP壓縮與解壓
Golang?中的?archive/zip?包用于處理?ZIP?格式的壓縮文件,提供了一系列用于創(chuàng)建、讀取和解壓縮?ZIP?格式文件的函數(shù)和類型,使用起來(lái)非常方便,下面就跟隨小編一起了解一下具體使用方法吧2023-08-08
Go語(yǔ)言defer語(yǔ)句的三種機(jī)制整理
在本篇文章里小編給大家分享的是一篇關(guān)于Go語(yǔ)言defer語(yǔ)句的三種機(jī)制整理,需要的朋友們學(xué)習(xí)下吧。2020-03-03
wind10 idea中 go 開(kāi)發(fā)環(huán)境搭建教程圖解
這篇文章主要介紹了wind10 idea中 go 開(kāi)發(fā)環(huán)境搭建過(guò)程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
golang 64位linux環(huán)境下編譯出32位程序操作
這篇文章主要介紹了golang 64位linux環(huán)境下編譯出32位程序操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
一文掌握Go語(yǔ)言并發(fā)編程必備的Mutex互斥鎖
Go 語(yǔ)言提供了 sync 包,其中包括 Mutex 互斥鎖、RWMutex 讀寫(xiě)鎖等同步機(jī)制,本篇博客將著重介紹 Mutex 互斥鎖的基本原理,需要的可以參考一下2023-04-04

