π¦ Rust Compound Types: Packing Multiple Things Together!
Imagine you have a lunchbox. Instead of carrying an apple in one hand, a sandwich in another, and a juice box balanced on your headβyou put them all inside the lunchbox. Thatβs what compound types do in Rust! They let you group multiple values together in one neat package.
π― What Are Compound Types?
Compound types are containers that hold multiple values. Rust has several kinds:
| Type | What It Is | Size |
|---|---|---|
| Tuple | A mixed lunchbox | Fixed |
| Array | A row of same things | Fixed |
| Slice | A window into an array | Flexible |
Think of it like this:
- Tuple = A lunchbox with apple + sandwich + juice (different items)
- Array = A carton of 6 eggs (same items)
- Slice = Looking at just 3 eggs from the carton
π¦ Tuples: The Mixed Lunchbox
A tuple is like a lunchbox where you can put different types of things together. Once you pack it, you canβt add moreβthe size is fixed.
Creating a Tuple
// A lunchbox with: age, height, initial
let person = (25, 5.9, 'A');
This tuple holds:
25β an integer (age)5.9β a float (height)'A'β a character (initial)
Getting Items Out
You can unpack everything at once:
let (age, height, initial) = person;
println!("Age: {}", age);
// Output: Age: 25
Or grab one item by its position (starting from 0):
let age = person.0; // First item
let height = person.1; // Second item
let initial = person.2; // Third item
π¨ Real Example
fn get_user() -> (String, i32, bool) {
(String::from("Alice"), 30, true)
}
let (name, age, active) = get_user();
println!("{} is {} years old", name, age);
// Output: Alice is 30 years old
π‘ Pro tip: Tuples are perfect for returning multiple values from a function!
π Arrays: The Egg Carton
An array is like an egg cartonβall items must be the same type, and the size is fixed when you create it.
graph TD A["Array: 5 slots"] --> B["0: π₯"] A --> C["1: π₯"] A --> D["2: π₯"] A --> E["3: π₯"] A --> F["4: π₯"]
Creating an Array
// 5 numbers in a row
let numbers = [10, 20, 30, 40, 50];
// 4 months of the same type
let months = ["Jan", "Feb", "Mar", "Apr"];
You can also create an array filled with the same value:
// 5 slots, all filled with 0
let zeros = [0; 5];
// Same as: [0, 0, 0, 0, 0]
Accessing Elements
Use square brackets with the index (position):
let first = numbers[0]; // 10
let third = numbers[2]; // 30
β οΈ Watch out! If you try
numbers[10]when there are only 5 items, Rust will panic (crash) to protect you!
π¨ Real Example
let days = ["Mon", "Tue", "Wed", "Thu", "Fri"];
for day in days {
println!("Today is {}", day);
}
Array vs Tuple
| Feature | Array | Tuple |
|---|---|---|
| Same type? | β Yes | β Mixed OK |
| Access by | arr[0] |
tup.0 |
| Use case | List of similar items | Group of related data |
π Slices: The Window View
A slice is like looking through a window at part of your array. You donβt own the dataβyou just borrow a view of it.
graph TD A["Array: 1,2,3,4,5"] --> B["Slice: 2,3,4"] style B fill:#e8f5e9
Creating a Slice from an Array
Use &array[start..end] to create a slice:
let numbers = [1, 2, 3, 4, 5];
// Get items from index 1 to 3
let slice = &numbers[1..4];
// slice = [2, 3, 4]
The start..end range:
- Includes the start index
- Excludes the end index
Different Slice Ranges
let arr = [10, 20, 30, 40, 50];
let a = &arr[0..2]; // [10, 20]
let b = &arr[..2]; // [10, 20] (same)
let c = &arr[2..]; // [30, 40, 50]
let d = &arr[..]; // All items!
π¨ Real Example
fn sum(slice: &[i32]) -> i32 {
let mut total = 0;
for num in slice {
total += num;
}
total
}
let nums = [1, 2, 3, 4, 5];
let all = sum(&nums); // 15
let some = sum(&nums[1..4]); // 9 (2+3+4)
π‘ Why slices? They let functions work with any size of data without copying!
π Slice from Array: The Complete Picture
Hereβs how arrays and slices work together:
graph TD A["Array: owns data"] -->|borrow| B["Slice: borrows view"] B --> C["Can read"] B --> D["Can iterate"] B --> E["Cannot resize"]
Key Points
- Array = You own the whole egg carton
- Slice = Youβre looking at some eggs through a window
- Slices borrow data, they donβt own it
Mutable Slices
You can also borrow a mutable slice to change values:
let mut nums = [1, 2, 3, 4, 5];
let slice = &mut nums[1..3];
slice[0] = 99; // Change 2 to 99
// nums is now [1, 99, 3, 4, 5]
π¨ Complete Example
fn double_values(slice: &mut [i32]) {
for num in slice {
*num *= 2;
}
}
let mut scores = [10, 20, 30, 40];
// Double just the first two
double_values(&mut scores[0..2]);
// scores = [20, 40, 30, 40]
π Quick Summary
| Type | Contains | Size | Access | Use Case |
|---|---|---|---|---|
| Tuple | Mixed types | Fixed | .0, .1 |
Return multiple values |
| Array | Same type | Fixed | [0], [1] |
Known-size collections |
| Slice | Same type | Flexible | [0], [1] |
Borrow part of array |
Memory Picture
Tuple (i32, f64, char):
βββββββββββ¬ββββββββββ¬ββββββββββ
β 25 β 5.9 β 'A' β
βββββββββββ΄ββββββββββ΄ββββββββββ
Array [i32; 5]:
βββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ
β 10 β 20 β 30 β 40 β 50 β
βββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ
[0] [1] [2] [3] [4]
Slice &[i32]:
βββββββββββββββ
βββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ
β 10 β 20 β 30 β 40 β 50 β
βββββββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ
[borrowed view]
π You Did It!
Now you know how to:
- β Pack different things in a tuple
- β Line up same things in an array
- β Look at parts with a slice
- β Create slices from arrays
These compound types are the building blocks for organizing data in Rust. Theyβre simple, safe, and super useful!
π§ββοΈ Remember: Tuples mix, Arrays line up, Slices peek!
