Home  >  Article  >  Backend Development  >  Is it okay to panic inside a defer function, especially when it's already panicked?

Is it okay to panic inside a defer function, especially when it's already panicked?

WBOY
WBOYforward
2024-02-11 20:33:08933browse

在 defer 函数内部发生恐慌是否可以,特别是当它已经发生恐慌时?

Will it have any impact when a panic occurs inside the defer function? This is a common question, especially if a panic situation has occurred. In PHP, the defer function is used to perform some cleanup operations before the current function returns. When a panic occurs, the program will stop execution immediately, and all defer functions will be executed in last-in-first-out order. Therefore, even after a panic occurs, the defer function will still be executed. This is useful for handling tasks such as resource release and error handling. No matter what happens, the defer function always executes reliably, ensuring the integrity and stability of the code.

Question content

func sub(){
    defer func (){
        panic(2)
    }()
    panic(1)
}

func main(){
    defer func(){
        x:=recover()
        println(x.(int));
    }()
    sub()
}

I tried this code and it seems that the first panic panic(1) is "overwritten" by the second panic panic(2).

But is it okay to do this? Or calling a Golang function that might panic inside a defer function?

(In C, throwing an exception from a destructor is almost unacceptable. If the stack has been unwound, it will terminate the program. I wonder if panicking in a similar way would be bad in Golang.)

Solution

Yes, it’s okay. The panic caused by the delay function is not really a new special state, it just means that the panic sequence will not stop.

Your sample code also proves that it's ok, even panic() called can be passed to recover() The "upper" level is called to stop the delay function.

Specifications: Handling Panics:

One thing to note here is that even if you call panic() within a delay function, all other delay functions will still run. Also, panic() without recover() from a deferred function would rather "wrap" the existing panic rather than "overwrite" it (although recover() The call does only return the last panic() call passed).

See this example:

func main() {
    defer func() {
        fmt.Println("Checkpoint 1")
        panic(1)
    }()
    defer func() {
        fmt.Println("Checkpoint 2")
        panic(2)
    }()
    panic(999)
}

Output (try it on Go Playground):

c2e572c1c34a0369ef7​989373914f540

Even if all deferred functions call panic(), all deferred functions are executed, and the final panic sequence printed contains the values ​​passed to all panic() calls.

If you call recover() within a deferred function, you will also get this "recovered" status or information in the final printout:

defer func() {
    recover()
    fmt.Println("Checkpoint 1")
    panic(1)
}()
defer func() {
    recover()
    fmt.Println("Checkpoint 2")
    panic(2)
}()

Output (try it on Go Playground):

Checkpoint 2
Checkpoint 1
panic: 999 [recovered]
    panic: 2 [recovered]
    panic: 1
...

The above is the detailed content of Is it okay to panic inside a defer function, especially when it's already panicked?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete