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 } }
现在换一种写法,我们将 i
的类型改成 interface{}
,i == nil
依然会生效
func main() { var i interface{} = nil if i == nil { fmt.Println("i is nil") // i is nil } }
我们接着改造,将 i == nil
的逻辑封装成函数 IsNil
func IsNil(i interface{}) { if i == nil { fmt.Println("i is nil") } } func main() { var i *int = nil IsNil(i) }
IsNil 中的 i == nil 不生效
然后居然发现 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>
但是如果我们在函数中用 interface{}
作为参数的类型,表示并不代表参数就是 interface{}
类型,而是任意类型,调用时传入啥类型就是啥类型,如下代码
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
所以只有当我们传入类型的参数是 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") } }
这个坑可能会出现在返回 error
的函数中,比如下面这段代码
在函数 SomeThing
中提前定义了 myError
,然后一系列的处理后,返回了 myError
业务逻辑
后面的业务逻辑需要判断 err
是否为 nil
type MyError struct{} func (me *MyError) Error() string { return "my error" } func SomeThing() error { var myError *MyError // 默认初始化为 nil // ... return myError } func main() { err := SomeThing() fmt.Println(reflect.TypeOf(err), reflect.ValueOf(err)) // *main.MyError <nil> if err != nil { // 虽然没有返回,这里会被执行,因为 err 的类型不是 nil fmt.Println(err) } }
从上面的代码我们看到,SomeThing
函数中定义的 myError
是 *MyError
类型,虽然返回了 nil
,但是 err
的类型不是 nil
,所以 err != nil
会生效,不符合预期
如果修改这个问题呢,当我们需要返回 nil
时,显示指明返回 nil
,如下代码:
type MyError struct{} func (me *MyError) Error() string { return "my error" } func SomeThing() error { var myError *MyError // 默认初始化为 nil // ... return nil } func main() { err := SomeThing() fmt.Println(reflect.TypeOf(err), reflect.ValueOf(err)) // <nil> <invalid reflect.Value> if err != nil { // 这段代码不会被执行 fmt.Println(err) } }
总结
需要返回 nil
时,要显示返回 nil
,不要用指针类型的零值
以上就是go nil处理如何正确返回nil的error的详细内容,更多关于go nil处理返回error的资料请关注脚本之家其它相关文章!
相关文章
go gin 正确读取http response body内容并多次使用详解
这篇文章主要为大家介绍了go gin 正确读取http response body内容并多次使用解决思路,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-01-01深入学习Golang并发编程必备利器之sync.Cond类型
Go 语言的 sync 包提供了一系列同步原语,其中 sync.Cond 就是其中之一。本文将深入探讨 sync.Cond 的实现原理和使用方法,帮助大家更好地理解和应用 sync.Cond,需要的可以参考一下2023-05-05
最新评论