Go Multiple Return Values

Functions returning multiple values in Go

🔄 What are Multiple Return Values?

Go functions can return multiple values simultaneously, making error handling and complex operations more efficient. This unique feature helps write cleaner, more expressive code.


// Function returning multiple values
func divide(a, b int) (int, string) {
    if b == 0 {
        return 0, "Cannot divide by zero"
    }
    return a / b, "Success"
}

func main() {
    result, message := divide(10, 2)
    fmt.Println("Result:", result, "Message:", message)
}
                                    

Output:

Result: 5 Message: Success

Key Multiple Return Concepts

📤

Declaration

Specify multiple return types in parentheses

func getName() (string, int) {
    return "Alice", 25
}
📥

Assignment

Assign multiple values using comma

name, age := getName()

Blank Identifier

Ignore unwanted return values with _

name, _ := getName() // Ignore age
🛡️

Error Handling

Common pattern for error handling

result, err := someFunction()
if err != nil {
    // handle error
}

🔹 Basic Multiple Return Values

Functions can return multiple values of different types:

package main

import "fmt"

// Function returning two values
func getPersonInfo() (string, int) {
    return "John", 30
}

// Function returning three values
func getCoordinates() (float64, float64, string) {
    return 40.7128, -74.0060, "New York"
}

func main() {
    // Receive multiple values
    name, age := getPersonInfo()
    fmt.Printf("Name: %s, Age: %d\n", name, age)
    
    lat, lng, city := getCoordinates()
    fmt.Printf("City: %s, Lat: %.4f, Lng: %.4f\n", city, lat, lng)
}

Output:

Name: John, Age: 30

City: New York, Lat: 40.7128, Lng: -74.0060

🔹 Error Handling Pattern

Common Go pattern: return result and error:

package main

import (
    "fmt"
    "errors"
)

// Function that might fail
func safeDivide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}

// Function with string error message
func validateAge(age int) (bool, string) {
    if age < 0 {
        return false, "Age cannot be negative"
    }
    if age > 150 {
        return false, "Age seems unrealistic"
    }
    return true, "Valid age"
}

func main() {
    // Handle division
    result, err := safeDivide(10, 2)
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Division result:", result)
    }
    
    // Handle validation
    valid, message := validateAge(25)
    fmt.Printf("Valid: %t, Message: %s\n", valid, message)
}

Output:

Division result: 5

Valid: true, Message: Valid age

🔹 Ignoring Return Values

Use blank identifier (_) to ignore unwanted return values:

package main

import "fmt"

func getStats() (int, int, float64) {
    return 100, 50, 75.5 // count, errors, average
}

func processData() (string, bool, error) {
    return "processed", true, nil
}

func main() {
    // Get only the count, ignore errors and average
    count, _, _ := getStats()
    fmt.Println("Count:", count)
    
    // Get only the status, ignore success flag and error
    status, _, _ := processData()
    fmt.Println("Status:", status)
    
    // Get only success flag and error, ignore status
    _, success, err := processData()
    fmt.Printf("Success: %t, Error: %v\n", success, err)
}

Output:

Count: 100

Status: processed

Success: true, Error: <nil>

🧠 Test Your Knowledge

How do you ignore a return value in Go?