Skip to content

Vec::splice

Vec methods · Collections

Level: reference · for working programmers

One line: Replace a range with an iterator, and receive what was removed.

pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, <I as IntoIterator>::IntoIter, A>
where
    R: RangeBounds<usize>,
    I: IntoIterator<Item = T>,

Stable since 1.21.0.

The general form of half this list. The replacement need not be the same length as the range, which is what splice adds over everything else:

range replacement what it does
non-empty non-empty replace
empty (i..i) non-empty insert at i
non-empty empty remove — the same as drain
.. anything replace the whole vector

Any IntoIterator works as the replacement: an array, a Vec, a range, an adapter chain.

The removed elements come back as an iterator. Ignoring them (let _ = v.splice(…)) drops them and still performs the replacement — the return value is not what drives the work.

Panics if the range is out of bounds or inverted.

Example

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

fn main() {
    // Replace a range with an iterator, and receive what was removed.
    let mut v = vec![1, 2, 3, 4, 5];
    let removed: Vec<i32> = v.splice(1..4, [20, 30]).collect();
    println!("removed {removed:?}  now {v:?}");

    // The replacement need not be the same length — that is the point.
    let mut v = vec!["a", "b", "c"];
    v.splice(1..2, ["x", "y", "z"]);
    println!("one out, three in: {v:?}");

    // An empty range inserts without removing.
    let mut v = vec![1, 4];
    v.splice(1..1, [2, 3]);
    println!("insert at 1: {v:?}");

    // An empty replacement removes without inserting — that is drain's job,
    // and splice does it too.
    let mut v = vec![1, 2, 3, 4];
    v.splice(1..3, []);
    println!("remove 1..3: {v:?}");

    // The removed elements are dropped if you ignore them, so `let _ =` is
    // enough when you only want the replacement to happen.
    let mut v = vec![0, 0, 0];
    let _ = v.splice(..2, [9]);
    println!("{v:?}");

    // Any IntoIterator works as the replacement, including another Vec
    // and an adapter chain.
    let mut v = vec![1, 2, 3];
    v.splice(..1, vec![7, 8]);
    println!("from a Vec: {v:?}");
    let mut v = vec![1, 2, 3];
    v.splice(1.., (10..13).map(|n| n * 2));
    println!("from an adapter: {v:?}");

    // Replacing the whole thing.
    let mut v = vec![1, 2, 3];
    let old: Vec<i32> = v.splice(.., [0]).collect();
    println!("old {old:?}  new {v:?}");
}

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

removed [2, 3, 4]  now [1, 20, 30, 5]
one out, three in: ["a", "x", "y", "z", "c"]
insert at 1: [1, 2, 3, 4]
remove 1..3: [1, 4]
[9, 0]
from a Vec: [7, 8, 2, 3]
from an adapter: [1, 20, 22, 24]
old [1, 2, 3]  new [0]

See also

Vec::splice in the standard library ↗