网站架构文案,手工外包加工网,龙岗网站建设公司哪家口碑好,商丘网站建设运营公司对于下面这段代码#xff0c;我们知道 i 实际上的值就是 nil#xff0c;所以 i nil 会生效
func main() {var i *int nilif i nil {fmt.Println(i is nil) // i is nil}
}现在换一种写法#xff0c;我们将 i 的类型改成 interface{}#xff0c;i nil 依然…对于下面这段代码我们知道 i 实际上的值就是 nil所以 i nil 会生效
func main() {var i *int nilif i nil {fmt.Println(i is nil) // i is nil}
}现在换一种写法我们将 i 的类型改成 interface{}i nil 依然会生效
func main() {var i interface{} nilif i nil {fmt.Println(i is nil) // i is nil}
}我们接着改造将 i nil 的逻辑封装成函数 IsNil
go复制代码func IsNil(i interface{}) {if i nil {fmt.Println(i is nil)}
}
func main() {var i *int nilIsNil(i)
}居然发现 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 nilvar 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)) // intvar j interface{} hello
fmt.Println(reflect.TypeOf(j)) // stringvar k interface{} nil
fmt.Println(reflect.TypeOf(k)) // nil所以只有当我们传入的参数类型是 interface{}且 value 为 nil 时i nil 才会生效 否则其他情况都不会生效
func main() {var i interface{} nilIsNil(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 nilif err ! nil { // 虽然没有返回这里会被执行因为 err 的类型不是 nilfmt.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.Valueif err ! nil { // 这段代码不会被执行fmt.Println(err)}
}总结需要返回 nil 时要显示返回 nil不要用指针类型的零值