Vec<T> in Depth
Creating Vectors
Vec<T> provides multiple constructors and conversion traits for creating empty vectors, pre-allocated vectors, and vectors initialized from arrays, slices, or iterators.
Summary of Vec<T> Construction Methods
| Constructor / Expression | Heap Allocation Behavior | Required Trait on T |
|---|---|---|
Vec::new() / Vec::default() |
Zero heap allocation (capacity == 0, const fn for Vec::new()) |
None (T: Sized) |
Vec::with_capacity(n) |
Allocates uninitialized space for n elements (len == 0, capacity == n) |
None (T: Sized) |
vec![a, b, c] |
Allocates exact capacity (3) and moves elements in |
None (T: Sized) |
vec![val; n] |
Allocates capacity n and clones val into each slot |
T: Clone |
Vec::from([a, b, c]) |
Moves elements from fixed-size array [T; N] into a heap buffer |
None (T: Sized) |
slice.to_vec() / Vec::from(slice) |
Allocates slice.len() and clones each element (memcpy for Copy) |
T: Clone |
iter.collect::<Vec<T>>() |
Pre-allocates size_hint().0 and collects iterator items |
None (T: Sized) |
Creating Empty and Pre-Allocated Vectors
Because Vec::new() is a const fn that does not allocate heap memory until the first element is pushed, an empty Vec<T> can be stored in const or static items and costs nothing to construct:
static EMPTY_NAMES: Vec<String> = Vec::new();
fn main() {
// 1. Empty vector with explicit type annotation on binding:
let mut numbers: Vec<i32> = Vec::new();
println!("Vec::new(): len={}, cap={}", numbers.len(), numbers.capacity());
numbers.push(10);
// 2. Pre-allocated vector via turbofish `Vec::<T>::with_capacity`:
let preallocated = Vec::<u64>::with_capacity(32);
println!(
"with_capacity(32): len={}, cap={}",
preallocated.len(),
preallocated.capacity()
);
println!("Static empty len: {}", EMPTY_NAMES.len());
}
Vec::new(): len=0, cap=0
with_capacity(32): len=0, cap=32
Static empty len: 0
Creating Vectors from Arrays, Slices, and Iterators
fn main() {
// 1. From a fixed-size array by value (moves Non-Copy Strings without cloning):
let from_array = Vec::from([String::from("alpha"), String::from("beta")]);
// 2. From a borrowed slice (clones elements via `to_vec()`):
let raw_slice: &[i32] = &[10, 20, 30];
let from_slice: Vec<i32> = raw_slice.to_vec();
// 3. From a range or iterator pipeline via `.collect()`:
let evens: Vec<i32> = (1..=5).map(|x| x * 2).collect();
println!("from_array: {from_array:?}");
println!("from_slice: {from_slice:?}");
println!("evens: {evens:?}");
}
from_array: ["alpha", "beta"]
from_slice: [10, 20, 30]
evens: [2, 4, 6, 8, 10]