首頁 >後端開發 >Golang >為什麼這個程式在結果中印出421?

為什麼這個程式在結果中印出421?

王林
王林轉載
2024-02-10 19:48:07952瀏覽

為什麼這個程式在結果中印出421?

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

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除