Rust — Vectors
Vec<T> — the workhorse collection
Growable, heap-allocated, holds one type:
let mut nums: Vec<i32> = Vec::new(); // empty
nums.push(10);
nums.push(20);
// macro shortcut — the common way:
let v = vec![1, 2, 3];
vec![] is a macro that builds a vector with initial values.
Adding and removing
let mut v = vec![1, 2];
v.push(3); // [1, 2, 3] add to end
v.pop(); // Some(3) remove from end → Option!
v.insert(0, 99); // [99, 1, 2] insert at index (shifts)
v.remove(0); // removes index 0, returns it
v.clear(); // empties everything
v.len(); // current count
Notice pop() returns Option<i32> — Some(last) or None if empty. Rust won't let you pretend removal always succeeds.
Accessing — two ways, different guarantees
let v = vec![10, 20, 30];
v[1]; // 20 — panics if out of bounds
v.get(5); // Option<&i32> → None — never panics
[i] | .get(i) | |
|---|---|---|
| Out of range | panic | None |
| Use when | index provably valid | index from user/data |
if let Some(val) = v.get(2) {
println!("found {}", val);
}
Ownership inside vectors
Elements are owned by the vector — moving the vector moves them all; iterating by reference borrows them:
let words = vec![String::from("a"), String::from("b")];
for w in &words { // borrow — words stays usable ✓
println!("{}", w);
}
println!("{} items", words.len()); // still fine
Dropping non-Copy elements out requires .remove()/.pop() or consuming iteration (into_iter()).
Iteration patterns
for n in &v { … } // read-only borrow
for n in &mut v { *n *= 2; } // mutate in place (dereference with *)
for n in v { … } // consume — v is gone after!
Common transformations
let v = vec![1, 2, 3, 4];
v.iter().sum::<i32>(); // 10
v.iter().max(); // Some(4)
v.contains(&3); // true
let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect(); // [2,4,6,8]
let evens: Vec<&i32> = v.iter().filter(|x| *x % 2 == 0).collect();
.map().filter().collect() is iterator-land; full treatment in its lesson.
Slices connect vectors to functions
fn sum_all(items: &[i32]) -> i32 {
items.iter().sum()
}
sum_all(&v); // works on Vec
sum_all(&[1, 2]); // AND arrays — slices unify both
Accept &[T] in function signatures; callers pass whatever they have.
Gotchas: indexing past end panics · mutating while iterating (compile error) ·
vec![0; n]vsvec![0; n].clone()confusion — the first already makes n copies.
Mini Practice
- Build a todo Vec<String>; push three, pop one, print len.
- Safe-get an index from user data via .get() + match.
- Double every element in place using &mut iteration.
- sum + max + contains on one vector.
- Write mean(nums: &[f64]) -> f64 handling empty input.
Next: tuples →
Related Topics
Frequently Asked Questions about Vectors
What is Vectors in Rust?
Vectors is a fundamental concept in Rust. This lesson explains it step by step with clear examples, making it easy for beginners to understand.
How do I learn Vectors?
Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Vectors.
Why is Vectors important in Rust?
Vectors is essential for Rust development. Understanding this concept will help you write better code and solve real-world problems more effectively.