关于go:go里边一个让新手误解让老炮犯错的小知识点

38次阅读

共计 1400 个字符,预计需要花费 4 分钟才能阅读完成。

问题:在一个 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 带来的便当了。

正文完
 0