首頁 > 後端開發 > Golang > 主體

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

DDD
發布: 2024-11-24 08:42:14
原創
643 人瀏覽過

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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板