Returning Values from Deferred Functions in Go
In Go, a defer function allows you to execute a block of code after the current function has returned or terminated. While it's possible to modify the returned parameters within a defer function, it's not possible to return a new set of values.
Consider the following code:
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 // Attempt to return new values } }() panic("Report format not recognized.") // ... }
In this code, the defer function attempts to return nil and err when a panic occurs. However, this won't work because defer functions cannot return values. Instead, the returned parameters, rep and err, must be modified within the defer function.
Additionally, there's a type mismatch in the code. The panic occurs with a string, while the type assertion expects an error. This will cause the program to panic again when trying to convert the recovered value to an error.
To fix the code, we need to:
The corrected code:
defer func() { if r := recover(); r != nil { fmt.Println("Recovered in f", r) // Find out the exact error type and set err switch x := r.(type) { case string: err = errors.New(x) case error: err = x default: err = errors.New("Unknown panic") } // Invalidate rep rep = nil } }()
With these changes, the defer function now correctly sets err and rep when a panic occurs, allowing the calling function to handle the error appropriately.
The above is the detailed content of Can Deferred Functions Return Values in Go?. For more information, please follow other related articles on the PHP Chinese website!