go nil處理如何正確返回nil的error
i == nil 會生效
對于下面這段代碼,我們知道 i
實際上的值就是 nil
,所以 i == nil
會生效
func main() { var i *int = nil if i == nil { fmt.Println("i is nil") // i is nil } }
現(xiàn)在換一種寫法,我們將 i
的類型改成 interface{}
,i == nil
依然會生效
func main() { var i interface{} = nil if i == nil { fmt.Println("i is nil") // i is nil } }
我們接著改造,將 i == nil
的邏輯封裝成函數(shù) IsNil
func IsNil(i interface{}) { if i == nil { fmt.Println("i is nil") } } func main() { var i *int = nil IsNil(i) }
IsNil 中的 i == nil 不生效
然后居然發(fā)現(xiàn) IsNil
中的 i == nil
不生效了,為什么呢?
因為對于 interface{}
類型的值來說,如果要判斷它是 nil
,必須同時滿足 type T
和 value V
都是 nil
才行
可以用 reflect
中的 TypeOf
和 ValueOf
var i *int = nil fmt.Println(reflect.TypeOf(i), reflect.ValueOf(i)) // *int <nil> var i interface{} = nil fmt.Println(reflect.TypeOf(i), reflect.ValueOf(i)) // <nil> <invalid reflect.Value>
但是如果我們在函數(shù)中用 interface{}
作為參數(shù)的類型,表示并不代表參數(shù)就是 interface{}
類型,而是任意類型,調(diào)用時傳入啥類型就是啥類型,如下代碼
var i interface{} = 1 fmt.Println(reflect.TypeOf(i)) // int var j interface{} = "hello" fmt.Println(reflect.TypeOf(j)) // string var k interface{} = nil fmt.Println(reflect.TypeOf(k)) // nil
所以只有當(dāng)我們傳入類型的參數(shù)是 interface{}
類型時,且 value
為 nil
時,i == nil
才會生效
否則其他情況都不會生效
func main() { var i interface{} = nil IsNil(i) // i is nil } func IsNil(i interface{}) { if i == nil { fmt.Println("i is nil") } }
這個坑可能會出現(xiàn)在返回 error
的函數(shù)中,比如下面這段代碼
在函數(shù) SomeThing
中提前定義了 myError
,然后一系列的處理后,返回了 myError
業(yè)務(wù)邏輯
后面的業(yè)務(wù)邏輯需要判斷 err
是否為 nil
type MyError struct{} func (me *MyError) Error() string { return "my error" } func SomeThing() error { var myError *MyError // 默認(rèn)初始化為 nil // ... return myError } func main() { err := SomeThing() fmt.Println(reflect.TypeOf(err), reflect.ValueOf(err)) // *main.MyError <nil> if err != nil { // 雖然沒有返回,這里會被執(zhí)行,因為 err 的類型不是 nil fmt.Println(err) } }
從上面的代碼我們看到,SomeThing
函數(shù)中定義的 myError
是 *MyError
類型,雖然返回了 nil
,但是 err
的類型不是 nil
,所以 err != nil
會生效,不符合預(yù)期
如果修改這個問題呢,當(dāng)我們需要返回 nil
時,顯示指明返回 nil
,如下代碼:
type MyError struct{} func (me *MyError) Error() string { return "my error" } func SomeThing() error { var myError *MyError // 默認(rèn)初始化為 nil // ... return nil } func main() { err := SomeThing() fmt.Println(reflect.TypeOf(err), reflect.ValueOf(err)) // <nil> <invalid reflect.Value> if err != nil { // 這段代碼不會被執(zhí)行 fmt.Println(err) } }
總結(jié)
需要返回 nil
時,要顯示返回 nil
,不要用指針類型的零值
以上就是go nil處理如何正確返回nil的error的詳細內(nèi)容,更多關(guān)于go nil處理返回error的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang中crypto/cipher加密標(biāo)準(zhǔn)庫全面指南
本文主要介紹了Golang中crypto/cipher加密標(biāo)準(zhǔn)庫,包括對稱加密、非對稱加密以及使用流加密和塊加密算法,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02Go語言通過chan進行數(shù)據(jù)傳遞的方法詳解
這篇文章主要為大家詳細介紹了Go語言如何通過chan進行數(shù)據(jù)傳遞的功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起了解一下2023-06-06