GoLang: 调用空对象的方法导致恐慌(panic)

huangapple go评论76阅读模式
英文:

GoLang: panic on call of nil object's method

问题

延迟函数:

func PrintPing(req *proto.PingRequest, resp *proto.PingResponse) {
    fmt.Println("resp:", resp)
    fmt.Println("resp.GetResult():", resp.GetResult())
}

当在发生 panic 后调用此函数时,respresp.GetResult() 都为 nil。

但为什么 resp.GetResult() 也是 nil 呢?控制台输出如下:

resp: <nil>
resp.GetResult(): <nil>

对于这种情况,是否有官方的定义?

英文:

Deferred function:

func PrintPing(req *proto.PingRequest, resp *proto.PingResponse) {
    fmt.Println(&quot;resp:&quot;, resp)
    fmt.Println(&quot;resp.GetResult():&quot;, resp.GetResult())
}

When this function is called after a panic, the resp and resp.GetResult() is nil.

But why resp.GetResult() is nil too? The console output:

resp: &lt;nil&gt;
resp.GetResult(): &lt;nil&gt;

Is there any official definition for this case?

答案1

得分: 5

我假设你的问题是为什么 resp.GetResult() 调用本身不会引发 panic,因为它是在一个空实例上调用的。

这是 Go 语言的工作方式。该方法也可以在实例为空的类型上调用。只要方法本身不访问实例,它就可以正常工作,并且可以实现对空实例的行为。

这与延迟函数无关。在其他上下文中也可以模拟这种情况:https://play.golang.org/p/qQanhQnIcL

英文:

I assume your question is why the resp.GetResult() call does not panic itself because it's called on a nil instance.

This is how Go works. The method can be called also on types where the instance is nil. As long as the method itself does not access the instance, it will work and behavior for nil instances can be implemented.

This has nothing to do with deferred functions. It can also be simulated in other contexts: https://play.golang.org/p/qQanhQnIcL

答案2

得分: 1

你的 proto.PingResponse 不仅仅是 nil,而是一种类型化的 nil。在 Go 语言中,它被称为零值

> 声明时没有显式初始化的变量会被赋予它们的零值。

访问类型的零值方法是可以的,如果该方法不执行可能导致零值恐慌的操作。

英文:

Your proto.PingResponse is not just nil but in some manner a typed nil. In Go terms it is zero value:

> Variables declared without an explicit initial value are given their zero value.

It is ok to have access to a method of zero value of type and not panic if the method doesn't do nothing which could cause panic on a zero value.

huangapple
  • 本文由 发表于 2017年1月9日 19:33:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/41547112.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定