Multiple Return Values in Go
One of Go’s most powerful and unique features is its ability to return multiple values from a single function. This feature is widely used in real-world Go programs, especially for handling results and errors together.
Instead of relying on exceptions, Go encourages returning both a result and an error explicitly.
Why Multiple Return Values Matter
- Cleaner error handling
- Clear separation of result and status
- No hidden exceptions
- Better readability and control
Basic Syntax
A function can return more than one value by listing multiple return types.
func functionName() (type1, type2) {
return value1, value2
}
Simple Example: Returning Two Numbers
This function returns both the sum and difference of two numbers.
package main
import "fmt"
func calculate(a int, b int) (int, int) {
return a + b, a - b
}
func main() {
sum, difference := calculate(20, 8)
fmt.Println("Sum:", sum)
fmt.Println("Difference:", difference)
}
Here, the function returns two values, which are assigned to two variables in a single statement.
Ignoring One Return Value
If you don’t need one of the returned values,
you can ignore it using the underscore (_).
total, _ := calculate(15, 5)
fmt.Println("Total:", total)
Real-World Example: Division with Remainder
This function returns both quotient and remainder.
package main
import "fmt"
func divide(a int, b int) (int, int) {
return a / b, a % b
}
func main() {
quotient, remainder := divide(100, 9)
fmt.Println("Quotient:", quotient)
fmt.Println("Remainder:", remainder)
}
This is commonly used in financial calculations, pagination logic, and batching systems.
Multiple Return Values with Error Handling
The most common use case for multiple return values is returning a result and an error.
package main
import (
"fmt"
"errors"
)
func withdraw(balance int, amount int) (int, error) {
if amount > balance {
return balance, errors.New("insufficient balance")
}
return balance - amount, nil
}
func main() {
newBalance, err := withdraw(30000, 45000)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Updated Balance:", newBalance)
}
}
This pattern avoids crashes and gives full control to the caller.
Named Return Values
Go allows naming return values directly in the function signature.
package main
import "fmt"
func stats(a int, b int) (sum int, product int) {
sum = a + b
product = a * b
return
}
func main() {
s, p := stats(6, 4)
fmt.Println("Sum:", s)
fmt.Println("Product:", p)
}
Named return values improve readability but should be used carefully to avoid confusion.
Best Practices
- Use multiple returns for result + error
- Avoid returning too many values
- Keep return values meaningful
- Prefer clarity over cleverness
Common Mistakes
- Ignoring returned errors
- Returning unrelated values
- Overusing named return values
Where This Is Used in Real Projects
- File operations
- Database queries
- API responses
- Financial calculations
What’s Next?
In the next lesson, you will learn about Variadic Functions, which allow functions to accept a variable number of arguments.