🎓 A1Learner
🔍

Rust Resize & Split a Vec

resize, truncate, split_off and append are four Vec tools that set a list size or split a list in two. resize changes a Vec to an exact length.

resize fills the new slots with copies

A bigger target pads with copies of the value you give. A smaller target cuts the Vec down:

let mut v = vec![1, 2];
v.resize(4, 9);
println!("grown = {:?}", v);
v.resize(1, 0);
println!("shrunk = {:?}", v);

resize_with builds each new item

When each new item must be made rather than copied, the closure runs once per new slot:

let mut v = vec![100];
let mut next = 100;
v.resize_with(4, || { next += 100; next });
println!("{:?}", v);

truncate keeps the front

truncate(n) drops everything after position n. The capacity stays, so the Vec can grow again into the same memory:

let mut v = vec![1, 2, 3, 4];
v.truncate(2);
println!("{:?} room for {}", v, v.capacity());

split_off hands you the back half

One Vec becomes two: this one keeps the front, the returned one takes the rest:

let mut v = vec![1, 2, 3, 4];
let tail = v.split_off(2);
println!("kept = {:?} tail = {:?}", v, tail);

append moves a whole Vec in

append takes every item out of another Vec and leaves it empty — no item-by-item copying:

let mut a = vec![1, 2];
let mut b = vec![3, 4];
a.append(&mut b);
println!("a = {:?} b = {:?}", a, b);

Example

fn main() {
    let mut front = vec!["ana", "bo"];
    front.resize(4, "empty");
    println!("row = {:?}", front);
    let mut back = front.split_off(2);
    println!("front = {:?} back = {:?}", front, back);
    back.truncate(1);
    println!("back trimmed = {:?}", back);
    front.append(&mut back);
    println!("joined = {:?} back now = {:?}", front, back);
}

Key points

  • resize(new_len, value) needs the fill value to be Clone — it copies the same value into every new slot
  • resize_with(new_len, closure) calls the closure once per new slot, in order.
  • Use it when each new item must be built, not copied
  • truncate keeps the capacity: the dropped items are gone, but the room stays for the next growth
  • split_off(at) panics if at is past the end — the same promise most index tools make
  • append is the mirror of split_off.
  • One moves items out into a new Vec.
  • The other moves a whole Vec in
  • resize reads better when one line must handle growing and shrinking alike.

In this example, a row of four seats starts with two names. resize(4, "empty") pads it with copies of "empty", giving the full row. split_off(2) cuts the row in two: front keeps ana and bo, back takes the two empty seats. truncate(1) trims back to a single seat. Finally append moves that seat into front and leaves back empty. The two halves are one row again, now three seats long.

Note

resize to a smaller size and truncate(n) end at the same Vec.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

After let tail = v.split_off(2); on vec![1, 2, 3, 4], what is left in v?