Advanced Return Techniques
Defer and Multiple Returns
Execution Order
func complexOperation() (result string, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("recovered from panic: %v", r)
}
}()
// Complex logic
result = "processed"
return
}
Functional Programming Approaches
Closure with Multiple Returns
func createMultiReturnFunc() func() (int, string) {
counter := 0
return func() (int, string) {
counter++
return counter, fmt.Sprintf("Iteration %d", counter)
}
}
Generics and Multiple Returns
Type-Flexible Returns
func processGeneric[T any](input T) (T, bool) {
// Generic processing logic
return input, true
}
Return Value Strategies
Strategy |
Description |
Use Case |
Error Propagation |
Passing errors up the call stack |
Robust error handling |
State Reporting |
Returning multiple state indicators |
Complex workflow management |
Computation Results |
Multiple computational outcomes |
Data transformation |
Advanced Error Handling
graph TD
A[Function Call] --> B{Multiple Return Values}
B --> C[Primary Result]
B --> D[Error Status]
D --> |Error Present| E[Detailed Error Handling]
D --> |No Error| F[Continue Processing]
Context-Aware Returns
func processWithContext(ctx context.Context) ([]byte, error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
default:
// Normal processing
return []byte("result"), nil
}
}
Preallocated Return Slices
func efficientMultiReturn() ([]int, []string) {
numbers := make([]int, 0, 10)
strings := make([]string, 0, 10)
// Efficient population
return numbers, strings
}
Concurrent Return Patterns
Channel-Based Multiple Returns
func concurrentComputation() (<-chan int, <-chan string) {
numberChan := make(chan int)
stringChan := make(chan string)
go func() {
numberChan <- 42
stringChan <- "completed"
close(numberChan)
close(stringChan)
}()
return numberChan, stringChan
}
Advanced Techniques with LabEx Recommendations
- Prefer explicit over implicit returns
- Use named returns for complex functions
- Minimize return value complexity
Error Wrapping and Enrichment
func enrichedErrorReturn() (data string, err error) {
result, originalErr := complexOperation()
if originalErr != nil {
err = fmt.Errorf("enhanced error: %w", originalErr)
return
}
return result, nil
}
Best Practices
- Keep return signatures clear and predictable
- Use multiple returns for comprehensive information
- Handle potential error scenarios
- Leverage Go's strong typing
By mastering these advanced return techniques, developers can create more robust, flexible, and maintainable Go applications with sophisticated return value strategies.