【问题标题】:Struct initialization with data from nil pointer使用来自 nil 指针的数据进行结构初始化
【发布时间】:2018-02-07 20:50:57
【问题描述】:

当使用来自可能的“nil”指针的数据初始化结构类型时,恐慌消息总是指在该指针中调用函数的第一行,而不是值。

https://play.golang.org/p/VgX59Y08syi

例如,如果你在上面的代码中交换第 20 行和第 21 行,panic 会发生在调用函数的行,而不是第一次取消对 nil 指针的引用。

为什么会发生这种情况,而不是发生在“myStruct.MyString”上的恐慌?

【问题讨论】:

  • 我怀疑 struct 字段的初始化顺序是否由规范规定(但未检查),因此编译器可以先执行一个字段(而不是源顺序)。
  • 出于速度原因,它可以自动这样做。即函数比其他任何东西都需要更长的时间来评估
  • 是的,没有指定顺序,所以没有理由假设一个字段会在另一个字段之前初始化。

标签: go


【解决方案1】:

通过将func (m *MyStruct) Sent() bool {(指针接收器)更改为func (m MyStruct) Sent() bool {(值接收器),您可以看到堆栈跟踪从

goroutine 1 [running]:
main.(*MyStruct).Sent(...)
    /tmp/sandbox520127412/main.go:14
main.main()
    /tmp/sandbox520127412/main.go:21 +0x1a

进入

goroutine 1 [running]:
main.MyStruct.Sent(...)
    /tmp/sandbox497151564/main.go:21
main.main()
    /tmp/sandbox497151564/main.go:21 +0x1a

这告诉我们 golang 对待指针接收器的方式不同。

如果您检查https://golang.org/ref/spec#Order_of_evaluation,则从未指定结构顺序。但是在这种情况下首先评估函数调用,就规范所述而言,在另一个版本的编译器中不能保证所提到的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多