Different type of Compound data type
Programming on tuples
Programming on array and slice
Different type of Compound data type
Rust mainly provides four core compound data types:
Tuples
Arrays
Slices
Structs (including tuple structs & unit structs)
Additionally, Enums are often discussed alongside compound types because they group data variants.
1️⃣ Tuple
A tuple groups values of different types.
Example
fn main() {
let person = ("Ashwani", 27, true);
println!("Name: {}", person.0);
println!("Age: {}", person.1);
println!("Active: {}", person.2);
}
Output
Name: Ashwani
Age: 27
Active: true
Key Points
Fixed size
Can mix different types
Indexed using .0, .1, etc.
2️⃣ Array
An array stores multiple values of the same type with fixed length.
Example
fn main() {
let numbers: [i32; 4] = [10, 20, 30, 40];
println!("First: {}", numbers[0]);
println!("Length: {}", numbers.len());
}
Output
First: 10
Length: 4
Key Points
Fixed size
Same data type
Stack allocated
3️⃣ Slice
A slice is a view into a portion of an array or vector.
Example
fn print_slice(slice: &[i32]) {
println!("{:?}", slice);
}
fn main() {
let arr = [1, 2, 3, 4, 5];
print_slice(&arr[1..4]);
}
Output
[2, 3, 4]
Key Points
Dynamically sized
Borrowed (&[T])
Does not own data
4️⃣ Struct (Named Fields)
A struct groups related data with names.
Example
struct User {
name: String,
age: u8,
active: bool,
}
fn main() {
let user = User {
name: String::from("Ashwani"),
age: 27,
active: true,
};
println!("{} is {} years old", user.name, user.age);
}
Output
Ashwani is 27 years old
Key Points
Fields have names
Can mix types
Very common in real projects
5️⃣ Tuple Struct
A tuple struct is a struct without field names.
Example
struct Point(i32, i32);
fn main() {
let p = Point(10, 20);
println!("x={}, y={}", p.0, p.1);
}
Output
x=10, y=20
6️⃣ Unit Struct
A unit struct has no fields.
Example
struct Marker;
fn main() {
let _m = Marker;
println!("Unit struct created");
}
Output
Unit struct created
Use Case
Marker types
Traits implementation
Compile-time behavior
7️⃣ Enum (Data-Carrying Enum)
Enums can store different kinds of data.
Example
enum Message {
Quit,
Move(i32, i32),
Write(String),
}
fn main() {
let msg = Message::Move(10, 20);
match msg {
Message::Move(x, y) => println!("Move to {}, {}", x, y),
_ => println!("Other message"),
}
}
Output
Move to 10, 20
Programming on tuples
1) Swap two values (generic tuple)
fn swap<T, U>(pair: (T, U)) -> (U, T) {
let (a, b) = pair;
(b, a)
}
fn main() {
let p = ("Rust", 2026);
println!("Original: {:?}", p);
println!("Swapped: {:?}", swap(p));
}
Output
Original: ("Rust", 2026)
Swapped: (2026, "Rust")
2) Return multiple values from a function (min, max)
fn min_max(a: i32, b: i32) -> (i32, i32) {
if a < b { (a, b) } else { (b, a) }
}
fn main() {
let (mn, mx) = min_max(40, 12);
println!("min = {}, max = {}", mn, mx);
}
Output
min = 12, max = 40
3) Nested tuple destructuring
fn main() {
let data = ((10, 20), ("A", "B"), true);
let ((x, y), (s1, s2), flag) = data;
println!("x={}, y={}", x, y);
println!("s1={}, s2={}", s1, s2);
println!("flag={}", flag);
}
Output
x=10, y=20
s1=A, s2=B
flag=true
4) Tuple indexing + updating tuple elements
fn main() {
let mut user = ("Ashwani", 27, true);
println!("Name: {}", user.0);
println!("Age: {}", user.1);
println!("Active: {}", user.2);
user.1 = 28;
user.2 = false;
println!("Updated: {:?}", user);
}
Output
Name: Ashwani
Age: 27
Active: true
Updated: ("Ashwani", 28, false)
5) One-element tuple vs parentheses literal
fn main() {
println!("One element tuple: {:?}", (99u32,));
println!("Just a number: {:?}", (99u32));
}
Output
One element tuple: (99,)
Just a number: 99
6) Tuple struct with methods (Point)
#[derive(Debug)]
struct Point(i32, i32);
impl Point {
fn move_by(self, dx: i32, dy: i32) -> Point {
Point(self.0 + dx, self.1 + dy)
}
}
fn main() {
let p = Point(5, 7);
println!("Before: {:?}", p);
let p2 = p.move_by(3, -2);
println!("After: {:?}", p2);
}
Output
Before: Point(5, 7)
After: Point(8, 5)
7) Tuple struct (Matrix) formatting like real matrix
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
fn pretty(m: Matrix) -> (String, String) {
let line1 = format!("| {:>4.1} {:>4.1} |", m.0, m.1);
let line2 = format!("| {:>4.1} {:>4.1} |", m.2, m.3);
(line1, line2)
}
fn main() {
let m = Matrix(1.1, 1.2, 2.1, 2.2);
println!("Debug: {:?}", m);
let (l1, l2) = pretty(m);
println!("{}", l1);
println!("{}", l2);
}
Output
Debug: Matrix(1.1, 1.2, 2.1, 2.2)
| 1.1 1.2 |
| 2.1 2.2 |
8) Using tuple as a key in HashMap
use std::collections::HashMap;
fn main() {
let mut grid: HashMap<(i32, i32), &'static str> = HashMap::new();
grid.insert((0, 0), "Home");
grid.insert((1, 0), "Shop");
grid.insert((1, 1), "Office");
println!("{:?}", grid.get(&(1, 1)));
println!("{:?}", grid.get(&(2, 2)));
}
Output
Some("Office")
None
9) Iterating a Vec of tuples + calculating total
fn main() {
let cart = vec![
("Apple", 2, 50), // (item, qty, price)
("Milk", 1, 60),
("Bread", 3, 40),
];
let mut total = 0;
for (name, qty, price) in cart {
let cost = qty * price;
total += cost;
println!("{} x{} = {}", name, qty, cost);
}
println!("Total = {}", total);
}
Output
Apple x2 = 100
Milk x1 = 60
Bread x3 = 120
Total = 280
10) Pattern matching on tuples (match)
fn describe(p: (i32, i32)) -> &'static str {
match p {
(0, 0) => "Origin",
(0, _) => "On Y-axis",
(_, 0) => "On X-axis",
_ => "Somewhere else",
}
}
fn main() {
println!("{}", describe((0, 0)));
println!("{}", describe((0, 5)));
println!("{}", describe((7, 0)));
println!("{}", describe((3, 4)));
}
Output
Origin
On Y-axis
On X-axis
Somewhere else
Programming on array and slice
Borrow full array as slice
fn print_slice(slice: &[i32]) {
println!("Slice: {:?}, length={}", slice, slice.len());
}
fn main() {
let numbers = [10, 20, 30, 40];
print_slice(&numbers);
}
Output
Slice: [10, 20, 30, 40], length=4
2️⃣ Slice a portion of an array
fn main() {
let data = [1, 2, 3, 4, 5, 6];
let part = &data[2..5];
println!("Sliced part: {:?}", part);
}
Output
Sliced part: [3, 4, 5]
3️⃣ Modify array using mutable slice
fn double_values(slice: &mut [i32]) {
for v in slice {
*v *= 2;
}
}
fn main() {
let mut nums = [1, 2, 3, 4];
double_values(&mut nums[1..3]);
println!("Updated array: {:?}", nums);
}
Output
Updated array: [1, 4, 6, 4]
4️⃣ Safe access using .get() on slice
fn main() {
let values = [10, 20, 30];
match values.get(5) {
Some(v) => println!("Value: {}", v),
None => println!("Index out of bounds"),
}
}
Output
Index out of bounds
5️⃣ Iterating over array vs slice
fn main() {
let arr = [5, 10, 15];
println!("Array iteration:");
for x in arr {
println!("{}", x);
}
println!("Slice iteration:");
for x in &arr[1..] {
println!("{}", x);
}
}
Output
Array iteration:
5
10
15
Slice iteration:
10
15
6️⃣ Empty slice behavior
fn main() {
let empty: [i32; 0] = [];
println!("Length: {}", empty.len());
println!("Slice equals empty slice: {}", &empty == &[]);
}
Output
Length: 0
Slice equals empty slice: true
7️⃣ Split array using slices
fn main() {
let scores = [90, 80, 70, 60, 50];
let first_half = &scores[..2];
let second_half = &scores[2..];
println!("First half: {:?}", first_half);
println!("Second half: {:?}", second_half);
}
Output
First half: [90, 80]
Second half: [70, 60, 50]
8️⃣ Passing array to function expecting slice
fn sum(slice: &[i32]) -> i32 {
slice.iter().sum()
}
fn main() {
let data = [1, 2, 3, 4];
println!("Sum = {}", sum(&data));
}
Output
Sum = 10
9️⃣ Using chunks() on slices
fn main() {
let nums = [1, 2, 3, 4, 5];
for chunk in nums.chunks(2) {
println!("{:?}", chunk);
}
}
Output
[1, 2]
[3, 4]
[5]
🔟 Pattern matching with slices
fn main() {
let values = [1, 2, 3];
match values.as_slice() {
[a, b, c] => println!("Three elements: {}, {}, {}", a, b, c),
_ => println!("Something else"),
}
}
Output
Three elements: 1, 2, 3
Top comments (0)