【发布时间】:2022-01-23 16:13:20
【问题描述】:
我有这个代码
package main
import "fmt"
type Foo struct {
Bar string
}
func (f *Foo) level4() {
fmt.Printf("Bar = %s\n", f.Bar)
}
func (f *Foo) level3() {
f.level4() // panics here, 2 levels down
}
func (f *Foo) level2() {
f.level3()
}
func (f *Foo) level1() {
f.level2()
}
type FooWrapper struct {
foo *Foo
}
func main() {
w := FooWrapper{}
w.foo.level1() // expected it to panic here, since foo is nil
}
正如预期的那样,运行它会给出
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x47f454]
但是,我预计 nil 指针取消引用会发生在 w.foo.level1(),因为 foo 是 nil。相反,它会调用级别 1、2 和 3 并在那里发生恐慌。为什么会这样?
【问题讨论】:
-
Go 方法本质上是语法糖。
func (f *Foo) level1()在功能上等同于func level1(*Foo)因此,在nil指针上调用指针接收器是完全有效的,并且调用方法不会取消引用指针接收器。 -
谢谢丹尼尔。如果不是评论,我会将其标记为已接受的答案,因为它确实回答了我的问题。但是,我仍然不明白为什么它会在
f.level4()而不是fmt.Printf("Bar = %s\n", f.Bar)然后出现恐慌 -
当它试图确定
f.Bar的值时,它会在调用Printf之前在level4内发生恐慌。
标签: go segmentation-fault