Skip to main content

Vectors

A vector is a growable, heap-allocated array that stores values of the same type in contiguous memory.

Think of Vec<T> as: “An array that can grow and shrink safely.”

let v = vec![1, 2, 3];
  • Stores elements of type i32
  • Allocated on the heap
  • Size can change at runtime

Explicit Type

let v: Vec<i32> = Vec::new();

Vec<T> is generic — it works with any type.

Key Characteristics of Vec<T>​

FeatureVector
SizeDynamic
MemoryHeap
Grow/Shrink✅ Yes
IndexingO(1)
OwnershipOwns elements
SafetyBounds-checked

Creating Vectors​

  • Empty Vector: let mut v: Vec<i32> = Vec::new();
  • Using vec! Macro: let v = vec![10, 20, 30];
  • Initialize with Repeated Values: let v = vec![0; 5]; Creates: [0, 0, 0, 0, 0]

Adding Elements​

Using push()

let mut v = Vec::new();

v.push(1);
v.push(2);
v.push(3);

Vector grows automatically.

Capacity vs Length

let mut v = Vec::with_capacity(5);

v.push(1);
v.push(2);

println!("Length: {}", v.len());
println!("Capacity: {}", v.capacity());
  • len() → number of elements
  • capacity() → allocated space

Accessing Elements​

Using Index (Risky)

let v = vec![10, 20, 30];
println!("{}", v[1]); // 20

Panic if index is out of bounds.

Safe Access Using .get()

let v = vec![10, 20, 30];

match v.get(5) {
Some(value) => println!("{}", value),
None => println!("Index out of bounds"),
}

Iterating Over Vectors​

Immutable Iteration

let v = vec![1, 2, 3];

for x in &v {
println!("{}", x);
}

Mutable Iteration

let mut v = vec![1, 2, 3];

for x in &mut v {
*x *= 2;
}

Vector becomes: [2, 4, 6]

Consuming Iteration

let v = vec![1, 2, 3];

for x in v {
println!("{}", x);
}

v is moved and can’t be used after.

Removing Elements​

Remove Last Element

let mut v = vec![1, 2, 3];
let last = v.pop();

last is Option<i32>

Remove by Index

let mut v = vec![10, 20, 30];
v.remove(1);

Vector becomes: [10, 30]

Slicing Vectors (&[T])​

Create a Slice

let v = vec![1, 2, 3, 4, 5];
let slice = &v[1..4];

Type: &[i32]

Why Slices Matter

  • No ownership transfer
  • Works for arrays and vectors
  • Ideal for function parameters
fn print_slice(slice: &[i32]) {
for x in slice {
println!("{}", x);
}
}

Vectors and Ownership​

Moving a Vector

let v1 = vec![1, 2, 3];
let v2 = v1; // ownership moved

v1 is no longer valid.

Borrowing a Vector

let v = vec![1, 2, 3];
print_vec(&v);

fn print_vec(v: &Vec<i32>) {
println!("{:?}", v);
}

Better:

fn print_vec(v: &[i32]) {
println!("{:?}", v);
}

Storing Different Types (Using Enums)​

Vectors can store only one type, but enums help.

enum Value {
Int(i32),
Float(f64),
Text(String),
}

let v = vec![
Value::Int(10),
Value::Float(3.14),
Value::Text(String::from("Rust")),
];

Common Vector Methods​

MethodPurpose
push()Add element
pop()Remove last
len()Number of elements
capacity()Allocated space
clear()Remove all
contains()Check value
sort()Sort elements

Arrays vs Vectors (Quick Recap)​

FeatureArrayVector
SizeFixedDynamic
MemoryStackHeap
Resize❌✅
Use caseKnown sizeRuntime data