Rust Tuples

Fixed-size collections of mixed types

📦 What are Rust Tuples?

Tuples are fixed-size collections that can store multiple values of different types together. They're perfect for grouping related data temporarily, returning multiple values from functions, and pattern matching in Rust programs.


fn main() {
    // Tuple with different types
    let person = ("Alice", 30, true);
    
    // Access elements by index
    println!("Name: {}", person.0);
    println!("Age: {}", person.1);
    println!("Is student: {}", person.2);
}
                                    

Output:

Name: Alice

Age: 30

Is student: true

Tuple Features

Tuple Characteristics

📏

Fixed Size

Size determined at compile time

let tuple = (1, 2, 3);
🎨

Mixed Types

Can store different data types

let mixed = (42, "hello", true);
🔢

Index Access

Access elements using dot notation

let first = tuple.0;
🔄

Destructuring

Unpack values into variables

let (x, y, z) = tuple;

🔹 Creating Tuples

Different ways to create tuples in Rust:

fn main() {
    // Basic tuple with mixed types
    let coordinates = (10.5, 20.3);
    
    // Tuple with explicit types
    let person: (&str, i32, bool) = ("Bob", 25, false);
    
    // Single element tuple (note the comma)
    let single = (42,);
    
    // Empty tuple (unit type)
    let unit = ();
    
    // Nested tuples
    let nested = ((1, 2), (3, 4));
    
    println!("Coordinates: {:?}", coordinates);
    println!("Person: {:?}", person);
    println!("Single: {:?}", single);
    println!("Unit: {:?}", unit);
    println!("Nested: {:?}", nested);
}

Output:

Coordinates: (10.5, 20.3)

Person: ("Bob", 25, false)

Single: (42,)

Unit: ()

Nested: ((1, 2), (3, 4))

🔹 Accessing Tuple Elements

Access tuple elements using dot notation with index:

fn main() {
    let student = ("Emma", 22, "Computer Science", 3.8);
    
    // Access individual elements
    println!("Name: {}", student.0);
    println!("Age: {}", student.1);
    println!("Major: {}", student.2);
    println!("GPA: {}", student.3);
    
    // Store elements in variables
    let name = student.0;
    let age = student.1;
    
    println!("Student {} is {} years old", name, age);
    
    // Modify tuple elements (tuple must be mutable)
    let mut scores = (85, 90, 78);
    scores.0 = 95;  // Change first score
    scores.2 = 88;  // Change third score
    
    println!("Updated scores: {:?}", scores);
}

Output:

Name: Emma

Age: 22

Major: Computer Science

GPA: 3.8

Student Emma is 22 years old

Updated scores: (95, 90, 88)

🔹 Tuple Destructuring

Unpack tuple values into separate variables:

fn main() {
    let point = (3.0, 4.0);
    
    // Destructure into separate variables
    let (x, y) = point;
    println!("Point coordinates: x={}, y={}", x, y);
    
    // Partial destructuring with underscore
    let rgb = (255, 128, 0);
    let (red, _, blue) = rgb;  // Ignore green component
    println!("Red: {}, Blue: {}", red, blue);
    
    // Destructuring in function parameters
    fn print_person(person: (&str, i32)) {
        let (name, age) = person;
        println!("{} is {} years old", name, age);
    }
    
    let alice = ("Alice", 28);
    print_person(alice);
    
    // Destructuring with different patterns
    let data = (1, (2, 3), 4);
    let (first, (second, third), fourth) = data;
    println!("Values: {}, {}, {}, {}", first, second, third, fourth);
}

Output:

Point coordinates: x=3, y=4

Red: 255, Blue: 0

Alice is 28 years old

Values: 1, 2, 3, 4

🔹 Tuples in Functions

Use tuples to return multiple values from functions:

fn main() {
    // Function returning a tuple
    fn get_name_and_age() -> (&'static str, i32) {
        ("John", 35)
    }
    
    let person = get_name_and_age();
    println!("Person: {:?}", person);
    
    // Destructure the returned tuple
    let (name, age) = get_name_and_age();
    println!("Name: {}, Age: {}", name, age);
    
    // Function that calculates multiple values
    fn calculate_stats(numbers: &[i32]) -> (i32, i32, f64) {
        let sum: i32 = numbers.iter().sum();
        let max = *numbers.iter().max().unwrap_or(&0);
        let average = sum as f64 / numbers.len() as f64;
        
        (sum, max, average)
    }
    
    let data = [10, 20, 30, 40, 50];
    let (total, maximum, avg) = calculate_stats(&data);
    
    println!("Sum: {}, Max: {}, Average: {:.2}", total, maximum, avg);
    
    // Function taking tuple as parameter
    fn distance_from_origin((x, y): (f64, f64)) -> f64 {
        (x * x + y * y).sqrt()
    }
    
    let point = (3.0, 4.0);
    let dist = distance_from_origin(point);
    println!("Distance from origin: {:.2}", dist);
}

Output:

Person: ("John", 35)

Name: John, Age: 35

Sum: 150, Max: 50, Average: 30.00

Distance from origin: 5.00

🔹 Tuple Methods and Operations

Working with tuples and common operations:

fn main() {
    let coordinates = (10, 20, 30);
    
    // Tuples implement Debug trait for printing
    println!("Debug print: {:?}", coordinates);
    
    // Tuples can be compared if all elements are comparable
    let point1 = (1, 2);
    let point2 = (1, 2);
    let point3 = (2, 1);
    
    println!("point1 == point2: {}", point1 == point2);
    println!("point1 == point3: {}", point1 == point3);
    
    // Tuples can be cloned if all elements are cloneable
    let original = (String::from("hello"), 42);
    let cloned = original.clone();
    println!("Original: {:?}", original);
    println!("Cloned: {:?}", cloned);
    
    // Using tuples in match expressions
    let status = (200, "OK");
    
    match status {
        (200, message) => println!("Success: {}", message),
        (404, message) => println!("Not found: {}", message),
        (code, message) => println!("Status {}: {}", code, message),
    }
    
    // Tuple as array indices (for 2D coordinates)
    let grid = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
    let position = (1, 2);  // row 1, column 2
    println!("Value at {:?}: {}", position, grid[position.0][position.1]);
}

Output:

Debug print: (10, 20, 30)

point1 == point2: true

point1 == point3: false

Original: ("hello", 42)

Cloned: ("hello", 42)

Success: OK

Value at (1, 2): 6

🧠 Test Your Knowledge

How do you access the second element of a tuple named 'data'?