</>
Skip to content
Rust lessons (23/43)

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 rangepanicNone
Use whenindex provably validindex 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] vs vec![0; n].clone() confusion — the first already makes n copies.

Mini Practice

  1. Build a todo Vec<String>; push three, pop one, print len.
  2. Safe-get an index from user data via .get() + match.
  3. Double every element in place using &mut iteration.
  4. sum + max + contains on one vector.
  5. 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.