Vec::insert¶
Level: reference · for working programmers
One line: Put an element at index, shifting everything after it to the right.
Stable since 1.0.0.
O(n − index), not O(1). Every element from index onwards moves one place. insert(0, x) is therefore the expensive one: it shifts the entire vector.
Building a list front-first with insert(0, …) is quadratic. Push and reverse ↗ once instead, or use a VecDeque if both ends are hot.
index == len() is legal and appends — that is the one past-the-end index that does not panic. Anything above it panics.
Removing several elements by index has the mirror problem: the indices move under you. Go back to front, or use retain, which is one pass and cannot get it wrong.
Example¶
vec_insert.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let mut v = vec!["Ada", "Cara"];
v.insert(1, "Ben");
println!("{v:?}");
// index == len is the one past-the-end index that is legal: it appends.
v.insert(v.len(), "Dana");
println!("append via insert: {v:?}");
// insert(0, ..) is the expensive one: every element shifts right.
let mut v = vec![3, 4, 5];
v.insert(0, 2);
v.insert(0, 1);
println!("front inserts: {v:?}");
// O(n - index), not O(1) — the elements after `index` are all moved.
// Building a list front-first with insert(0, ..) is quadratic; pushing
// and reversing once is linear.
let mut by_insert = Vec::new();
for n in 1..=5 { by_insert.insert(0, n); }
let mut by_push = Vec::new();
for n in 1..=5 { by_push.push(n); }
by_push.reverse();
println!("{by_insert:?} == {by_push:?}: {}", by_insert == by_push);
// index > len panics. Catching it here so the page can show the message.
let hook = std::panic::take_hook();
std::panic::set_hook(Box::new(|_| {}));
let caught = std::panic::catch_unwind(|| {
let mut v = vec![1, 2, 3];
v.insert(9, 0);
});
std::panic::set_hook(hook);
println!("insert(9, ..) into a len-3 vec panicked: {}", caught.is_err());
}
Verified output of vec_insert.rs — regenerated by tools/run_examples.py, never hand-typed.
["Ada", "Ben", "Cara"]
append via insert: ["Ada", "Ben", "Cara", "Dana"]
front inserts: [1, 2, 3, 4, 5]
[5, 4, 3, 2, 1] == [5, 4, 3, 2, 1]: true
insert(9, ..) into a len-3 vec panicked: true
See also¶
Vec::insert_mut— the same, returning a handle on the new elementVec::push— the O(1) case, at the endVec::remove— the inverse, with the same costVec::splice— inserting many at once