Common Standard Macros
vec!
The vec! macro constructs a heap-allocated Vec<T> from an inline list of elements (vec![a, b, c]) or by repeating a value $n$ times (vec![elem; n]).
Expansion of the Three vec! Rules
macro_rules! vec {
// 1. Empty vector (zero heap allocation):
() => {
$crate::vec::Vec::new()
};
// 2. Repeat value `elem` `n` times (requires `T: Clone`):
($elem:expr; $n:expr) => {
$crate::vec::from_elem($elem, $n)
};
// 3. Comma-separated element list (single exact-sized Box<[T]> allocation):
($($x:expr),+ $(,)?) => {
<[_]>::into_vec(std::boxed::Box::new([$($x),+]))
};
}
| Invocation | Expansion Strategy | Heap Allocations |
|---|---|---|
vec![] |
Vec::new() |
0 (capacity == 0) |
vec![x, y, z] |
Allocates Box<[T; 3]> directly on the heap and converts its pointer into Vec<T> |
1 (len == 3, capacity == 3) |
vec![val; n] |
Calls vec::from_elem(val, n) (uses calloc / OS zero pages when val is all-zero bits!) |
1 (len == n, capacity == n) |
Using vec! with List and Repeat Syntax
fn main() {
// 1. Empty vector:
let empty: Vec<i32> = vec![];
// 2. Element list (moves non-Copy Strings without cloning):
let names = vec![
String::from("node-1"),
String::from("node-2"),
];
// 3. Repeat syntax with a runtime length `n`:
let count = 4;
let zeroes = vec![0_u16; count];
println!("empty: {empty:?} (cap={})", empty.capacity());
println!("names: {names:?} (cap={})", names.capacity());
println!("zeroes: {zeroes:?} (cap={})", zeroes.capacity());
}
empty: [] (cap=0)
names: ["node-1", "node-2"] (cap=2)
zeroes: [0, 0, 0, 0] (cap=4)
Difference Between vec![x; n] and [x; N]
- Runtime vs. compile-time length: In an array literal
[x; N],Nmust be a compile-timeconst usize. Invec![x; n],ncan be any runtimeusizevariable. - Trait requirement (
Clonevs.Copy):[x; N]requiresT: Copy(unlessxis aconstblock/item), whereasvec![x; n]only requiresT: Clone, cloningxinto the firstn - 1slots and movingxinto the final slot.