Introduction
A vector, Vec<T>, is Rust's growable, heap-allocated collection for storing multiple values of the same type in a contiguous, resizable block of memory. Unlike arrays, whose length is fixed at compile time, vectors can grow or shrink at runtime, making them the go-to collection for lists whose size isn't known ahead of time.
Cricket analogy: A Vec<T> is like a team's squad list for a tour that can add or drop players as the series progresses, unlike a fixed playing XI array locked at toss time — vectors are the go-to when squad size isn't known ahead of the tournament.
Syntax
let mut numbers: Vec<i32> = Vec::new();
let mut fruits = vec!["apple", "banana", "cherry"];
numbers.push(10);
numbers.push(20);
let last = numbers.pop();Explanation
Vec::new() creates an empty vector, while the vec![...] macro creates and initializes one in a single step. Adding elements to the end is done with .push(), and removing the last element with .pop(), which returns an Option<T> (None if the vector is empty). You can access elements by index with numbers[0], but this panics if the index is out of bounds; the safer alternative is .get(index), which returns Option<&T> so you can handle a missing index without crashing. To iterate over all elements without taking ownership, use for x in &my_vec, which yields references to each element.
Cricket analogy: Vec::new() is like starting an empty squad list, while vec![...] drafts the initial squad in one go; .push() adds a new signing, .pop() releases the last-added player and returns None if the squad's empty, numbers[0] panics if you query a non-existent slot but .get(index) safely returns None, and for x in &my_vec reviews each player by reference without transferring ownership.
Example
fn main() {
let mut numbers = vec![1, 2, 3];
numbers.push(4);
for n in &numbers {
println!("value: {}", n);
}
match numbers.get(10) {
Some(v) => println!("found: {}", v),
None => println!("index 10 is out of bounds"),
}
println!("length: {}", numbers.len());
}
// Output:
// value: 1
// value: 2
// value: 3
// value: 4
// index 10 is out of bounds
// length: 4Key Takeaways
- Vec<T> is a growable, heap-allocated, homogeneous list.
- Use
vec![...]to create and initialize a vector concisely. .push()and.pop()add and remove elements from the end.- Indexing with
[]panics out of bounds;.get()returnsOption<&T>for safe access. for x in &my_veciterates by reference without taking ownership of the vector.
Practice what you learned
1. What happens when you index a Vec out of bounds using `v[10]` on a shorter vector?
2. Which method provides safe, non-panicking access to a vector element?
3. What macro is commonly used to create and initialize a vector in one line?
4. What does `.pop()` return on an empty vector?
5. How do you iterate over a vector's elements without taking ownership of the vector?
Was this page helpful?
You May Also Like
HashMaps in Rust
HashMap<K, V> stores key-value pairs, giving fast average-case lookup by key at the cost of unordered iteration.
The Option Type in Rust
Understand how Rust's Option<T> enum replaces null to represent optional values safely.
Slices in Rust
Slices are references to a contiguous sequence of elements within a collection, letting you view data without owning it.
Tuples and Arrays in Rust
Tuples group a fixed set of differently-typed values together, while arrays hold a fixed-size list of same-typed values.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics