【问题标题】:What does *(*int)(nil) = 0 mean in golang?*(*int)(nil) = 0 在 golang 中是什么意思?
【发布时间】:2020-11-09 12:13:14
【问题描述】:

我注意到函数throw中有一行*(*int)(nil) = 0

//go:nosplit
func throw(s string) {
    // Everything throw does should be recursively nosplit so it
    // can be called even when it's unsafe to grow the stack.
    systemstack(func() {
        print("fatal error: ", s, "\n")
    })
    gp := getg()
    if gp.m.throwing == 0 {
        gp.m.throwing = 1
    }
    fatalthrow()
    *(*int)(nil) = 0 // not reached
}

*(*int)(nil) = 0 是什么意思?并且由于这条线*(*int)(nil) = 0 无法到达,为什么它在这里?有什么特殊用法吗?

【问题讨论】:

  • 它是panic("unreachable") 的编译器内部变体。

标签: go pointers


【解决方案1】:

行:

*(*int)(nil) = 0

尝试取消引用 nil 指针并为其分配值,这始终是运行时恐慌。代码永远不会到达这一行,但如果它无论如何都会到达(例如,将来发生错误的代码更改),它会恐慌,因此可以检测到错误并且不会被忽视。

在您的代码中也做类似的事情是常识,但使用更明显的“构造”,例如panic("unreachable")。例如:

func sign(a int) string {
    switch {
    case a > 0:
        return "Positive"
    case a < 0:
        return "Negative"
    case a == 0:
        return "Zero"
    default:
        panic("unreachable")
    }
}

请注意,在此示例中,这不仅仅是为了及早检测错误,这也是一项要求,因为对于编译器而言,无法保证会到达 return 语句。您也可以将panic("unreachable") 语句移到switch 之后(而不是default 分支),这只是个人喜好问题。

如果您将上述函数更改为不返回但打印符号,则让default 分支处于恐慌状态仍然是一个好习惯,尽管这不是此变体中的要求:

func printSign(a int) {
    switch {
    case a > 0:
        fmt.Println("Positive")
    case a < 0:
        fmt.Println("Negative")
    case a == 0:
        fmt.Println("Zero")
    default:
        panic("unreachable")
    }
}

【讨论】:

    猜你喜欢
    • 2016-06-29
    • 2019-03-30
    • 2016-07-14
    • 1970-01-01
    • 2015-08-28
    • 2011-06-05
    • 1970-01-01
    • 2015-03-20
    • 2020-01-07
    相关资源
    最近更新 更多