slice::swap¶
Level: reference · for working programmers
One line: Exchange the elements at two indices.
Stable since 1.0.0; const since 1.85.0.
v.swap(0, 3) and the two elements have traded places. a == b is allowed and does nothing. Either index out of range panics.
It exists because the obvious spelling is refused: std::mem::swap(&mut v[0], &mut v[3]) is error[E0499]: cannot borrow `v` as mutable more than once — two &mut into one vector, and the borrow checker cannot see that the indices differ. swap takes the indices, checks them once, and does the exchange inside std where the aliasing is provably fine.
reverse is a loop of swaps from both ends; Vec::swap_remove is a swap with the last element followed by a pop.
Example¶
slice_swap.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let mut v = vec!["a", "b", "c", "d"];
v.swap(0, 3);
println!("{v:?}");
v.swap(1, 1);
println!("{v:?} <- a == b is a no-op");
// std::mem::swap(&mut v[0], &mut v[3]) is error[E0499]: two &mut into one Vec.
// swap takes indices instead and does the exchange inside std.
// reverse, by hand: swap from both ends inward.
let mut w = vec![1, 2, 3, 4, 5];
let n = w.len();
for i in 0..n / 2 {
w.swap(i, n - 1 - i);
}
println!("{w:?}");
// The panic is caught here so the program can report it and go on.
let hook = std::panic::take_hook();
std::panic::set_hook(Box::new(|_| {}));
let r = std::panic::catch_unwind(move || w.swap(0, 9));
std::panic::set_hook(hook);
println!("swap(0, 9) on 5 elements panicked: {}", r.is_err());
}
Verified output of slice_swap.rs — regenerated by tools/run_examples.py, never hand-typed.
["d", "b", "c", "a"]
["d", "b", "c", "a"] <- a == b is a no-op
[5, 4, 3, 2, 1]
swap(0, 9) on 5 elements panicked: true
See also¶
slice::reverse— swaps from both endsslice::get_mut— why two&mutat once needs helpslice::rotate_left— move a whole run, not two elements