首頁 >後端開發 >Golang >為什麼 `recover()` 在 Go 的巢狀延遲函數中不起作用?

為什麼 `recover()` 在 Go 的巢狀延遲函數中不起作用?

DDD
DDD原創
2024-11-24 08:42:14686瀏覽

Why Doesn't `recover()` Work in Nested Deferred Functions in Go?

為什麼Recover() 在巢狀延遲函數中失敗

考慮以下Golang 程式碼:

package main

import "fmt"

func printRecover() {
    r := recover()
    fmt.Println("Recovered:", r)
}

func main() {
    defer printRecover()

    panic("OMG!")
}

這個簡單的程式成功地發生恐慌並恢復以下輸出:

Recovered: OMG!

但是,修改將printRecover()包裝在另一個延遲函數中的程式碼會導致不同的結果:

package main

import "fmt"

func printRecover() {
    r := recover()
    fmt.Println("Recovered:", r)
}

func main() {
    defer func() {
        printRecover()
    }()

    panic("OMG!")
}

在這種情況下,恐慌不會恢復,導致程式崩潰:

Recovered: <nil>
panic: OMG!

goroutine 1 [running]:
main.main()
    /tmp/sandbox898315096/main.go:15 +0x60

這種行為的解釋在於golang 中的recover() 運作方式。根據語言規格:

The return value of recover is nil if any of the following conditions holds:

- panic's argument was nil;
- the goroutine is not panicking;
- recover was not called directly by a deferred function.

在第一個範例中,recover() 是由延遲函數直接呼叫的,因此它成功檢索了恐慌參數。然而,在第二個範例中,recover() 不是由延遲函數直接調用,而是由本身由延遲函數調用的函數調用。結果recover()回傳nil,恐慌沒有恢復。

以上是為什麼 `recover()` 在 Go 的巢狀延遲函數中不起作用?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn