Skip to content

Vec::resize_with

Vec methods · Collections

Level: reference · for working programmers

One line: resize, calling a closure once per new slot.

pub fn resize_with<F>(&mut self, new_len: usize, f: F)
where
    F: FnMut() -> T,

Stable since 1.33.0.

No Clone bound, and a fresh value per slot rather than n clones of one. v.resize_with(3, Vec::new) gives three independent empty vectors; Default::default is the other common argument.

The closure is FnMut, so it can count — resize_with(5, || { n += 1; n * n }) fills with squares.

Shrinking never calls it. Same as resize: the tail is dropped and the closure is untouched.

Which to use is a real choice, not a style preference: resize clones one prototype, resize_with builds each element. For a Vec<Vec<T>> grid the prototype version is wasted work, and for a non-Clone element type it does not compile at all.

Stable since 1.33.0.

Example

vec_resize_with.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.

fn main() {
    // The closure is called once per new slot, so each value is fresh.
    let mut v = vec![1, 2];
    v.resize_with(5, || 0);
    println!("{v:?}");

    // That is the difference from resize: no Clone bound, and a new value
    // rather than n clones of one.
    let mut rows: Vec<Vec<u8>> = vec![vec![9]];
    rows.resize_with(3, Vec::new);
    rows[1].push(1);
    println!("{rows:?}");

    // The closure is FnMut, so it can count.
    let mut n = 0;
    let mut v: Vec<u32> = Vec::new();
    v.resize_with(5, || { n += 1; n * n });
    println!("squares: {v:?}");

    // Shrinking never calls it.
    let mut calls = 0;
    let mut v = vec![1, 2, 3];
    v.resize_with(1, || { calls += 1; 0 });
    println!("shrunk to {v:?}, closure called {calls} times");

    // Default::default is the common argument.
    let mut v: Vec<String> = Vec::new();
    v.resize_with(2, Default::default);
    println!("{v:?}");

    // A grid built with independent rows — the bug resize() would introduce
    // here is not aliasing (Rust has no aliasing clone) but wasted work:
    // resize would clone one prototype row n times.
    let mut grid: Vec<Vec<u8>> = Vec::new();
    grid.resize_with(3, || Vec::with_capacity(4));
    for (i, row) in grid.iter_mut().enumerate() { row.push(i as u8); }
    println!("{grid:?}");
}

Verified output of vec_resize_with.rs — regenerated by tools/run_examples.py, never hand-typed.

[1, 2, 0, 0, 0]
[[9], [1], []]
squares: [1, 4, 9, 16, 25]
shrunk to [1], closure called 0 times
["", ""]
[[0], [1], [2]]

See also

Vec::resize_with in the standard library ↗