代码之家  ›  专栏  ›  技术社区  ›  ynn

当调用“recover()”时,会向调用方返回什么值?

  •  1
  • ynn  · 技术社区  · 1 年前

    首先要注意,这个问题是有意标记的 #language-lawyer :

    • 需要进行相对严格的理论(而非实证)讨论。

    • 此后,让我们使用 the language spec 作为讨论的参考。

    1.简介

    严格来说 ,将向的调用方返回什么值 f1() f2() ?

    //`T` is some type.
    func f1() T {
        defer func() {
            if r := recover(); r != nil {
                fmt.Println("recover")
            }
        }()
        g() //panics
        return something
    }
    
    //`T` is some type.
    func f2() (v T) {
        defer func() {
            if r := recover(); r != nil {
                fmt.Println("recover")
            }
        }()
        v = X //assignment
        g() //panics
        return something
    }
    

    就我的测试而言, f1() 返回的零值 T f2() 退货 X .

    2.问题

    行为是否由规范或UB(未定义的行为)保证? (后一种情况可以改写为“允许实现Go编译器吗 f1() 例如,返回类型为的统一随机值 T ?")

    Handling panics 说(强调我的):

    recover函数允许程序管理惊慌失措的goroutine的行为。假设函数G推迟了调用recover的函数D,并且在G执行的同一goroutine上的函数中发生了死机。当延迟函数的运行达到D时,D调用recover的返回值将是传递给panic调用的值。如果D正常返回,没有引发新的恐慌,恐慌序列就会停止。在这种情况下,在G和调用panic之间调用的函数的状态将被丢弃,并恢复正常执行。然后运行G在D之前延迟的任何函数,并且 G的执行通过返回到调用方而终止 .

    它根本没有解释将具体返回给的调用者的值 G .

    1 回复  |  直到 1 年前
        1
  •  1
  •   Brits    1 年前

    Return statements 规范的一节中指出:

    无论它们是如何声明的,在进入函数时,所有结果值都会初始化为其类型的零值。指定结果的“return”语句在执行任何延迟函数之前设置结果参数。

    所以,除非你通过 return 语句或修改命名结果参数时,将返回零值。