Vec<T> in Depth

split_off() and truncate()

Vec<T> provides .split_off(at) to partition a vector at index at into two independent owned vectors, and .truncate(len) (along with .resize(new_len, val)) to shorten or adjust a vector's length in place.

Splitting a Vector into Two Owned Halves with split_off(at)

pub fn split_off(&mut self, at: usize) -> Vec<T>

Calling v.split_off(at) keeps elements 0..at in v (preserving v's original capacity) and moves elements at..len into a newly allocated Vec<T> returned to the caller. It panics if at > v.len().

Before: v = [ 10, 20, 30, 40, 50 ]
                      ▲ (at = 2)
let right = v.split_off(2):
  v     = [ 10, 20 ]         (keeps original buffer & capacity)
  right = [ 30, 40, 50 ]     (newly allocated Vec<i32>)

(Note: If you only need borrowed views of the two halves without allocating a second Vec<T>, use the slice methods v.split_at(mid) or v.split_at_mut(mid) instead.)

fn main() {
    let mut left = vec![10, 20, 30, 40, 50];
    let right = left.split_off(2);

    println!("left:  {left:?} (cap={})", left.capacity());
    println!("right: {right:?} (cap={})", right.capacity());
}
left:  [10, 20] (cap=5)
right: [30, 40, 50] (cap=3)

Shortening or Resizing a Vector with truncate() and resize()

Method Signature When new_len < len When new_len >= len
v.truncate(new_len) fn truncate(&mut self, len: usize) Drops elements in new_len..len and sets self.len = new_len (keeps capacity) No-op (does nothing; never panics)
v.resize(new_len, val) fn resize(&mut self, new_len: usize, value: T) (T: Clone) Truncates to new_len Appends clones of value until len == new_len
v.resize_with(new_len, f) fn resize_with<F: FnMut() -> T>(&mut self, new_len: usize, f: F) Truncates to new_len Calls f() to generate each new element until len == new_len
fn main() {
    let mut data = vec![1, 2, 3, 4, 5];

    // 1. Shorten to 3 elements (drops 4 and 5):
    data.truncate(3);
    println!("After truncate(3):   {data:?} (cap={})", data.capacity());

    // 2. Passing a length >= current len to `truncate` is a safe no-op:
    data.truncate(100);
    println!("After truncate(100): {data:?}");

    // 3. Grow to length 6 by filling new slots with 0:
    data.resize(6, 0);
    println!("After resize(6, 0):  {data:?}");
}
After truncate(3):   [1, 2, 3] (cap=5)
After truncate(100): [1, 2, 3]
After resize(6, 0):  [1, 2, 3, 0, 0, 0]