理解巢狀延遲函數中的recover()限制
在Golang中,panic和recover提供了錯誤處理和恢復的機制。雖然recover()透過傳回恐慌值來幫助處理恐慌,但其行為在巢狀延遲函數中會改變。
範例1:簡單延遲函數
考慮以下程式碼片段:
package main import "fmt" func printRecover() { r := recover() fmt.Println("Recovered:", r) } func main() { defer printRecover() panic("OMG!") // Recoverable panic }
這段程式碼會出現「OMG!」恐慌並使用延遲的printRecover()函數成功恢復恐慌值,如輸出所示:
Recovered: OMG!
範例 2:巢狀延遲函數
現在,讓我們將 printRecover()包裝在另一個延遲函數中:
package main import "fmt" func printRecover() { r := recover() fmt.Println("Recovered:", r) } func main() { defer func() { printRecover() }() panic("OMG!") // Panic goes unrecoverable }
中在這個例子中,恐慌變得不可恢復,程式恐慌並顯示以下訊息:
Recovered: <nil> panic: OMG! goroutine 1 [running]: main.main() /tmp/sandbox898315096/main.go:15 +0x60
理解差異
這兩個範例之間的差異在於方式呼叫recover()。根據 Golang 規範:
在範例 1 中,printRecover() 直接由延遲函數呼叫deferred 函數,允許它傳回恐慌值。然而,在範例 2 中, printRecover() 由匿名函數調用,然後被延遲。這會導致recover()傳回nil,因為它不是由延遲函數直接呼叫。
因此,要成功恢復巢狀延遲函數中的恐慌,必須直接從延遲函數呼叫recover()。
以上是Go 中巢狀延遲函數與非巢狀延遲函數的「recover()」行為有何不同?的詳細內容。更多資訊請關注PHP中文網其他相關文章!