๐ Vectors in Rust: Your Magic Backpack!
Imagine you have a magic backpack that can grow bigger or smaller whenever you need. You can put toys in, take toys out, and even peek at whatโs inside. Thatโs exactly what a Vector is in Rust!
๐ What is a Vector?
A Vector (or Vec) is like a stretchy bag that holds a list of things. Unlike a regular bag with fixed size, this one grows when you add more stuff!
graph TD A["๐ Empty Vector"] --> B["Add Apple ๐"] B --> C["Add Banana ๐"] C --> D["Add Cherry ๐"] D --> E["๐ Vector with 3 items!"]
Real Life Examples:
- Your toy collection that keeps growing
- A list of your favorite songs
- Names of your friends
๐ฆ Creating Vectors
There are two easy ways to create a vector!
Way 1: Start Empty and Add Later
let mut toys: Vec<String> = Vec::new();
// An empty backpack, ready for toys!
Think of this like getting a new, empty backpack on your birthday. Itโs empty now, but youโll fill it with treasures!
Way 2: Use the Magic vec! Spell
let fruits = vec!["apple", "banana", "cherry"];
// Backpack already has 3 fruits!
This is like buying a backpack that already has some things inside. Super convenient!
โจ The vec! Macro - Your Magic Spell
The vec! macro is like saying a magic word that creates a vector instantly with items inside.
// Numbers in your backpack
let numbers = vec![1, 2, 3, 4, 5];
// Colors in your backpack
let colors = vec!["red", "blue", "green"];
// Same item repeated 3 times
let zeros = vec![0; 3]; // [0, 0, 0]
๐ฏ Quick Comparison
| Method | When to Use |
|---|---|
Vec::new() |
Start empty, add later |
vec![...] |
Know items upfront |
vec![x; n] |
Same item n times |
โ Updating Vectors
Your magic backpack has special powers to change!
Adding Items with push()
let mut snacks = vec!["cookie"];
snacks.push("candy"); // Now: [cookie, candy]
snacks.push("chips"); // Now: [cookie, candy, chips]
Itโs like putting a new toy at the bottom of your backpack!
Removing the Last Item with pop()
let mut snacks = vec!["cookie", "candy"];
let last = snacks.pop();
// last = Some("candy")
// snacks = ["cookie"]
pop() takes out whatever is on top and gives it to you.
Insert at a Specific Spot
let mut letters = vec!['a', 'c'];
letters.insert(1, 'b');
// Now: ['a', 'b', 'c']
Like squeezing a book between two others on a shelf!
Remove from a Specific Spot
let mut nums = vec![1, 2, 3];
nums.remove(1); // Removes the 2
// Now: [1, 3]
๐ Reading Vector Elements
How do you peek inside your backpack?
Way 1: Use Square Brackets []
let pets = vec!["dog", "cat", "bird"];
let first = pets[0]; // "dog"
let second = pets[1]; // "cat"
โ ๏ธ Warning! If you ask for something that doesnโt exist, your program panics (crashes)!
let oops = pets[99]; // ๐ฅ CRASH!
Way 2: Use .get() - The Safe Way
let pets = vec!["dog", "cat", "bird"];
let maybe = pets.get(99);
// Returns None, no crash!
.get() is like a gentle hand that says โMaybe thereโs something, maybe not.โ
graph TD A["Want Item?"] --> B{Use get or index?} B -->|"pets[i]"| C["Might Crash! ๐ฅ"] B -->|"pets.get#40;i#41;"| D["Safe! Returns Option"]
The Option Magic Box
match pets.get(1) {
Some(pet) => println!("Found: {}", pet),
None => println!("Nothing there!"),
}
๐ Iterating Over Vectors
Iterating means visiting each item one by one, like saying hello to every toy in your backpack!
Just Looking (Borrowing)
let fruits = vec!["apple", "banana"];
for fruit in &fruits {
println!("Hello, {}!", fruit);
}
// fruits still usable here!
Looking and Changing (Mutable Borrow)
let mut scores = vec![1, 2, 3];
for score in &mut scores {
*score += 10; // Add 10 to each
}
// scores = [11, 12, 13]
The * is like opening the box to change whatโs inside.
Taking Everything Out
let toys = vec!["ball", "doll"];
for toy in toys {
println!("Playing with {}", toy);
}
// toys is GONE now! Used up.
graph TD A["Iterate Options"] --> B["&vec = Borrow<br/>Look only"] A --> C["&mut vec = Change<br/>Look & modify"] A --> D["vec = Consume<br/>Take ownership"]
๐ Vector Capacity
Your backpack has a secret size - how much it CAN hold before needing to grow!
Length vs Capacity
let mut nums = Vec::with_capacity(10);
nums.push(1);
nums.push(2);
println!("Length: {}", nums.len()); // 2
println!("Capacity: {}", nums.capacity()); // 10
- Length = How many items ARE inside
- Capacity = How many items CAN fit
Why Care About Capacity?
When the backpack gets full, Rust needs to:
- Buy a bigger backpack
- Move everything over
- Throw away the old one
This takes time! If you know youโll need 1000 items, tell Rust upfront:
// Smart: Reserve space first
let mut big = Vec::with_capacity(1000);
// Less smart: Keep growing
let mut small = Vec::new();
Checking and Reserving
let mut v = vec![1, 2, 3];
v.reserve(100); // Make room for 100 more!
v.shrink_to_fit(); // Trim extra space
๐ฏ Quick Summary
| Task | Code |
|---|---|
| Create empty | Vec::new() |
| Create with items | vec![1, 2, 3] |
| Add to end | .push(item) |
| Remove from end | .pop() |
| Get safely | .get(index) |
| Loop through | for x in &vec |
| Check size | .len() |
| Check capacity | .capacity() |
๐ Youโre Ready!
You now know how to use Vectors - Rustโs amazing, growable lists! Theyโre like magic backpacks that:
- โ Grow when you need more space
- โ Let you peek at any item
- โ Let you add and remove things
- โ Are super efficient when you plan ahead
Go build something awesome! ๐
