Vec is the default collection in Rust; most data you process will pass through one.
`Vec<T>` is a growable, heap-allocated array of T. Create one with Vec::new(), Vec::with_capacity(n) when you know roughly how many elements are coming, or the vec![1, 2, 3] macro.
Adding and removing: push, pop (returns Option<T>), insert(i, x), remove(i) (shifts later elements, O(n)), swap_remove(i) (O(1), does not preserve order), extend, truncate, clear, retain(|x| ...) to filter in place, and dedup after a sort.
Reading: v[i] panics if out of bounds, while v.get(i) returns an Option<&T>. Use get when the index comes from outside your control.
Because a Vec<T> derefs to a slice [T], every slice method is available: len, is_empty, contains, iter, sort, sort_by_key, binary_search, windows, chunks, first, last, split_at, and more. So you can pass &v wherever a &[T] is expected.
Iteration comes in three flavours:
for x in &vborrows each element (&T),for x in &mut vgives&mut Tfor in-place edits,for x in vconsumes the vector and yields ownedT.
Under the hood a Vec is a pointer, a length and a capacity. When len reaches capacity, pushing reallocates (roughly doubling) and moves all elements. That is why the borrow checker forbids holding a reference into a vector across a push. shrink_to_fit releases spare capacity.
To store values of different types in one Vec, wrap them in an enum or use trait objects (covered later).
Example
fn main() {
let mut scores: Vec<u32> = Vec::with_capacity(4);
scores.extend([70, 95, 82]);
scores.push(95);
println!("{:?} {:?}", scores.get(10), scores.first()); // None Some(70)
for s in &mut scores {
*s += 5; // in-place edit through &mut
}
scores.sort_unstable();
scores.dedup();
scores.retain(|&s| s >= 80);
println!("{scores:?} len={} cap>={}", scores.len(), scores.capacity()); // [87, 100] len=2 cap>=4
let pairs: Vec<&[u32]> = [1, 2, 3, 4].windows(2).collect::<Vec<_>>();
println!("{pairs:?}"); // [[1, 2], [2, 3], [3, 4]]
let total: u32 = scores.into_iter().sum(); // consumes the vector
println!("{total}"); // 187
}Remember
- Use
vec![]orVec::with_capacity;getreturnsOption,[]panics - A
Vecderefs to a slice, so all slice methods apply &v,&mut vandvin aforloop borrow, mutably borrow, or consume
Watch out for
- Calling
remove(0)repeatedly on a large Vec (O(n) each); useVecDequefor queue behaviour.