Vec::new¶
Level: reference · for working programmers
One line: An empty vector that has not allocated anything yet.
Stable since 1.0.0. Callable in a const context since 1.39.0.
Vec::new() allocates nothing. It writes three numbers — a dangling pointer, length 0, capacity 0 — and the first push is what asks the allocator for a buffer. Creating one you may never fill is therefore free, which is why this is the default constructor rather than with_capacity.
It is the one Vec constructor usable in a const or static initialiser: static EMPTY: Vec<u8> = Vec::new(); compiles.
The type has to come from somewhere. Vec::new() alone is Vec<_>, and the compiler needs an annotation, a later push, or a typed binding to settle it — otherwise error[E0282]: type annotations needed forVec<_>``.
vec![] and Default::default() produce exactly the same thing — but a non-empty vec![…] does not behave like new plus pushes: it allocates its length exactly, so vec![1, 2, 3] has capacity 3 where three pushes give 4. See capacity. Vec::new() followed immediately by pushes is what clippy::vec_init_then_push ↗ (warn by default) rewrites into a vec![] literal.
A Vec of a zero-sized type never allocates whatever you push into it, and reports usize::MAX capacity: there is no buffer, so there is nothing to exhaust.
Example¶
vec_new.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
// `new` allocates nothing. An empty Vec is three numbers and no heap.
let v: Vec<i32> = Vec::new();
println!("len {} cap {} empty {}", v.len(), v.capacity(), v.is_empty());
// The type has to come from somewhere: an annotation, or later use.
let mut inferred = Vec::new();
inferred.push("Ada"); // now it is a Vec<&str>
println!("{inferred:?}");
// Three spellings of the same empty vector.
let a: Vec<u8> = Vec::new();
let b: Vec<u8> = vec![];
let c: Vec<u8> = Default::default();
println!("{} {}", a == b, b == c);
// The first push is what allocates, and it jumps straight past 1.
let mut v: Vec<u32> = Vec::new();
println!("before push: cap {}", v.capacity());
v.push(1);
println!("after push: cap {}", v.capacity());
// A Vec of a zero-sized type never allocates at all.
let mut zst: Vec<()> = Vec::new();
for _ in 0..1000 { zst.push(()); }
println!("1000 units: len {} cap is usize::MAX {}", zst.len(), zst.capacity() == usize::MAX);
}
Verified output of vec_new.rs — regenerated by tools/run_examples.py, never hand-typed.
len 0 cap 0 empty true
["Ada"]
true true
before push: cap 0
after push: cap 4
1000 units: len 1000 cap is usize::MAX true
See also¶
Vec::with_capacity— the same thing, with the buffer up frontVec::capacity— what the zero means, and when it stops being zeroVec::push— the call that actually allocates- The
Vec— the three numbers, and how they grow