go nil處理如何正確返回nil的error
i == nil 會(huì)生效
對(duì)于下面這段代碼,我們知道 i 實(shí)際上的值就是 nil,所以 i == nil 會(huì)生效
func main() {
var i *int = nil
if i == nil {
fmt.Println("i is nil") // i is nil
}
}現(xiàn)在換一種寫法,我們將 i 的類型改成 interface{},i == nil 依然會(huì)生效
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 不生效了,為什么呢?
因?yàn)閷?duì)于 interface{} 類型的值來說,如果要判斷它是 nil,必須同時(shí)滿足 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>但是如果我們?cè)诤瘮?shù)中用 interface{} 作為參數(shù)的類型,表示并不代表參數(shù)就是 interface{} 類型,而是任意類型,調(diào)用時(shí)傳入啥類型就是啥類型,如下代碼
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{} 類型時(shí),且 value 為 nil 時(shí),i == nil 才會(huì)生效
否則其他情況都不會(huì)生效
func main() {
var i interface{} = nil
IsNil(i) // i is nil
}
func IsNil(i interface{}) {
if i == nil {
fmt.Println("i is nil")
}
}這個(gè)坑可能會(huì)出現(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 { // 雖然沒有返回,這里會(huì)被執(zhí)行,因?yàn)?err 的類型不是 nil
fmt.Println(err)
}
}從上面的代碼我們看到,SomeThing 函數(shù)中定義的 myError 是 *MyError 類型,雖然返回了 nil,但是 err 的類型不是 nil,所以 err != nil 會(huì)生效,不符合預(yù)期
如果修改這個(gè)問題呢,當(dāng)我們需要返回 nil 時(shí),顯示指明返回 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 { // 這段代碼不會(huì)被執(zhí)行
fmt.Println(err)
}
}總結(jié)
需要返回 nil 時(shí),要顯示返回 nil,不要用指針類型的零值
以上就是go nil處理如何正確返回nil的error的詳細(xì)內(nèi)容,更多關(guān)于go nil處理返回error的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang實(shí)現(xiàn)獲取與解析命令行參數(shù)
這篇文章主要為大家詳細(xì)介紹了Golang如何實(shí)現(xiàn)獲取與解析命令行參數(shù),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以參考一下2024-01-01
Golang實(shí)現(xiàn)Redis事務(wù)深入探究
這篇文章主要介紹了Golang實(shí)現(xiàn)Redis事務(wù)深入探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
解決golang結(jié)構(gòu)體tag編譯錯(cuò)誤的問題
這篇文章主要介紹了解決golang結(jié)構(gòu)體tag編譯錯(cuò)誤的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-05-05

