问题:在一个 nil 变量上调用函数,会产生什么?
个别会认为 panic。为了不产生 panic,每次调用办法前,都要判断变量是否为 nil。这么做尽管没错,但究竟使代码看起来不那么优雅。
那么肯定会 panic 吗?
让咱们来做个试验
type PlanConfig struct {No int64}
func (p *PlanConfig) IsEmpty() bool {
if p == nil {fmt.Println("hello")
return false
}
return reflect.ValueOf(*p).IsZero()}
var p *PlanConfig
fmt.Println(p)
fmt.Println(p.IsEmpty())
该代码会输入
<nil>
hello
false
能够看到,新申明的指针类型变量 p,是 nil,然而并不障碍他调用 IsEmpty()办法。
如果强制赋 nil 呢,还会执行吗?
type PlanConfig struct {No int64}
func (p *PlanConfig) IsEmpty() bool {
if p == nil {fmt.Println("hello")
return false
}
return reflect.ValueOf(*p).IsZero()}
var p *PlanConfig
fmt.Println(p)
p = nil
fmt.Println(p.IsEmpty())
仍然输入
<nil>
hello
false
是不是很倔强。
再模仿一下咱们理论代码中的用法,比方从一个函数获取某个变量,然而返回值 nil,而后用这个变量调用办法
type PlanConfig struct {No int64}
func (p *PlanConfig) IsEmpty() bool {
if p == nil {fmt.Println("hello")
return false
}
return reflect.ValueOf(*p).IsZero()}
func getPlan() *PlanConfig {return nil}
p := getPlan()
fmt.Println(p.IsEmpty())
输入
hello
false
这样咱们只须要在办法的入口处判断一次即可,而不必每次调用办法前,都判断变量是否为 nil 了。
咱们再看看,程序会崩的状况。
type PlanConfig struct {No int64}
func (p *PlanConfig) IsEmpty() bool {
if p == nil {fmt.Println("hello")
return false
}
return reflect.ValueOf(*p).IsZero()}
p := nil
fmt.Println(p.IsEmpty())
ide 间接会飘红。执行代码也会抛出谬误
use of untyped nil
再看这种
type PlanConfig struct {No int64}
func (p *PlanConfig) IsEmpty() bool {return reflect.ValueOf(*p).IsZero()}
func getPlan() *PlanConfig {return nil}
p := getPlan()
fmt.Println(p.IsEmpty())
这一次,咱们在办法 IsEmpty()入口处去掉 nil 判断,后果的确会产生 panic。
论断:
用指针作为办法接收者的时候,只有咱们在函数入口处做是否为 nil 的判断,那么就能够纵情去享受 go 带来的便当了。