Vec & Slices
Vec<T> owns a growable buffer. &[T] borrows a contiguous view into Vec, arrays, or other data.
Recipe
fn sum(slice: &[i32]) -> i32 {
slice.iter().sum()
}
fn main() {
let v = vec![1, 2, 3];
println!("{}", sum(&v));
println!("{:?}", &v[1..]);
}When to reach for this: Default dynamic array; expose &[T] in read APIs.
Working Example
fn dedup_sorted(v: &mut Vec<i32>) {
v.sort_unstable();
v.dedup();
}
fn main() {
let mut data = vec![3, 1, 2, 2, 3];
dedup_sorted(&mut data);
println!("{:?}", data);
}What this demonstrates:
sort_unstable+dedupin-place- Mutable
Vecpassed by&mut - Slice
&v[1..]shares backing buffer
Deep Dive
len, capacity, reserve, shrink_to_fit, split_at, windows, chunks. Vec deref coerces to [T].
Gotchas
- Index panic -
v[i]out of bounds. Fix:get(i). - Iterating while mutating - Borrow conflict. Fix: Separate passes or
retain. - Excess capacity memory -
shrink_to_fitafter large temp build. - drain semantics - Removes range while iterating.
- Zero-sized types -
Vec<()>odd capacity behavior - edge case.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
SmallVec | Usually small | Always heap ok |
ArrayVec | Fixed max, stack | Unbounded growth |
Box<[T]> | Immutable sized slice owned | Need push |
FAQs
with_capacity?
When len known approx.from_raw_parts?
Unsafe - avoid unless expert.splice?
Replace range with iterator.truncate?
Drop tail elements.as_slice?
Explicit &[T] from Vec.mem::take?
Replace vec with empty quickly.align?
Vec aligns to T requirements.serde Vec?
Default seq serialization.no_std?
alloc::vec::Vec with alloc crate.sort stable?
sort vs sort_unstable tradeoff.Related
- Collections Basics
- IntoIterator & Owned vs Borrowed
- References & Slices
- Entry API & In-Place Updates
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.