php小編小新在這篇文章中將為您解答一個常見問題:「為什麼這個程式在結果中列印421?」這個問題可能涉及到程式中的某些特定邏輯或錯誤。我們將透過分析可能的原因和解決方法來幫助您理解並解決這個問題。請繼續閱讀以獲取詳細的答案。
我不明白,為什麼這個程式會印 421
而不是 431
?
package main import "fmt" var x int func f() int { x++ return x } func main() { o := fmt.println defer o(f()) defer func() { defer o(recover()) o(f()) }() defer f() defer recover() panic(f()) }
下面我加入了我猜測的評論:
package main import "fmt" var x int func f() int { x++ return x } func main() { o := fmt.Println defer o(f()) // x=1 defer func() { defer o(recover()) // x=3 from panic (but if we ll execute this program we ll see 2) o(f()) // x=4 }() defer f() // x=2 defer recover() //nil panic(f()) // x=3 }
defer
確實不呼叫該函數,但它recover() 的呼叫僅在從延遲函數呼叫時停止緊急狀態(defer receive()
不符合此條件)。請參閱為什麼`deferrecover()`不會捕捉恐慌?
鑑於此:讓我們對行進行編號:
L1: o := fmt.Println L2: defer o(f()) // x = 1 L3: defer func() { L4: defer o(recover()) // recover() returns 2 L5: o(f()) // x = 4, it gets printed L6: }() L7: defer f() // after panic: x = 3 L8: defer recover() L9: panic(f()) // x = 2
上面程式碼的執行程序如下:
l2:評估o()
的參數,呼叫f()
,x
遞增到1
(稍後將列印) 。 o()
尚未被呼叫。
l3:延遲函數尚未調用,暫時跳過其整個主體。
l7: f()
尚未被調用,x
仍為 1
。
l8: recover()
未被呼叫。
l9:呼叫f()
,將x
遞增到2
,然後返回,因此2
被傳遞給 panic()
。
我們處於恐慌狀態,因此現在執行延遲函數(按 lifo 順序)。
l8: recover()
被呼叫但不會停止恐慌狀態。
l7: f()
現在被調用,將 x
增加到 3
。
l3:這個匿名函數現在被執行。
l4:recover()
傳回2
(傳遞給panic()
的值),這將稍後列印,但尚未列印,因為對 o()
的呼叫被延後。恐慌狀態到此為止。
l5:呼叫 f()
,將 x
遞增到 4
,立即列印出來。
l4:延遲函數 o()
現在被執行,印出上面的值 2
。
l2:延遲函數 o()
現在被執行,列印先前計算的值 1
。
程式結束。
以上是為什麼這個程式在結果中印出421?的詳細內容。更多資訊請關注PHP中文網其他相關文章!