Skip to content

slice::swap

slice methods · Collections

Level: reference · for working programmers

One line: Exchange the elements at two indices.

pub const fn swap(&mut self, a: usize, b: usize)

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::swap in the standard library ↗