Panic Recovery with Local Variables
In Go, panic recovery using defer functions can modify named return values within the surrounding function. However, when local variables are used as return values, this mechanism does not function as expected.
Consider the following example where named return values (result and err) are modified within the defer function:
<code class="go">func main() { result, err := foo() fmt.Println("result:", result) if err != nil { fmt.Println("err:", err) } } func foo() (result int, err error) { defer func() { if e := recover(); e != nil { result = -1 err = errors.New(e.(string)) } }() bar() result = 100 err = nil return } func bar() { panic("panic happened") }</code>
This code recovers from a panic and correctly modifies the named return values result and err. However, consider the following example where local variables are used as return values:
<code class="go">func main() { result, err := foo() fmt.Println("result:", result) if err != nil { fmt.Println("err:", err) } } func foo() (int, error) { var result int var err error defer func() { if e := recover(); e != nil { result = -1 err = errors.New(e.(string)) } }() bar() result = 100 err = nil return result, err } func bar() { panic("panic happened") }</code>
In this case, the defer function is unable to modify the result and err variables, resulting in unexpected output where result remains 0.
This behavior arises from the fact that the defer statement applies to the function literal, not the surrounding function itself. Consequently, the local variables (result and err) are not accessible within the function literal. In contrast, named return values are accessible within the function literal since they are essentially variables initialized at the beginning of the function.
The above is the detailed content of Can Defer Functions Modify Local Variables During Panic Recovery in Go?. For more information, please follow other related articles on the PHP Chinese website!