Deferring a Return in Go
In Go, the defer statement allows the execution of a function to be postponed until the surrounding function returns. This allows for cleanup tasks to be executed even in the event of panic, which can occur when unrecoverable errors occur during runtime.
Consider the following code snippet that attempts to return an error from a function if it panics:
func getReport(filename string) (rep report, err error) { rep.data = make(map[string]float64) defer func() { if r := recover(); r != nil { fmt.Println("Recovered in f", r) err, _ = r.(error) return nil, err } }() panic("Report format not recognized.") // rest of the getReport function }
However, this code doesn't work as intended. The return statement within the deferred function only modifies the local variables err and rep within the function and does not actually return them outside the function.
To resolve this issue, we can use the recover function inside the deferred function to retrieve the panic value and set the err parameter accordingly. Additionally, we should check the type of the panic value and convert it to an error if necessary.
Here's an updated code:
defer func() { if r := recover(); r != nil { fmt.Println("Recovered in f", r) switch x := r.(type) { case string: err = errors.New(x) case error: err = x default: err = errors.New("Unknown panic") } rep = nil } }()
This code ensures that the err parameter is set to the appropriate error based on the panic value, and it also invalidates the rep parameter to prevent returning an incomplete report.
The above is the detailed content of How to Handle Panics and Defer Returns in Go Functions?. For more information, please follow other related articles on the PHP Chinese website!