Vec::splice¶
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::drain— the same removal, with no replacementVec::insert— one element, at a pointVec::extend_from_slice— appending rather than replacingVec::extract_if— removing by predicate instead of by range