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