Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I swap items in a vector, slice, or array in Rust?

Tags:

rust

People also ask

What is a VEC in Rust?

Vector is a module in Rust that provides the container space to store values. It is a contiguous resizable array type, with heap-allocated contents. It is denoted by Vec<T>. Vectors in Rust have O(1) indexing and push and pop operations in vector also take O(1) complexity.

How do you make an empty vector rust?

In Rust, there are several ways to initialize a vector. In order to initialize a vector via the new() method call, we use the double colon operator: let mut vec = Vec::new(); This call constructs a new, empty Vec<T> .


There is a swap method defined for &mut [T]. Since a Vec<T> can be mutably dereferenced as a &mut [T], this method can be called directly:

fn main() {
    let mut numbers = vec![1, 2, 3];
    println!("before = {:?}", numbers);
    numbers.swap(0, 2);
    println!("after = {:?}", numbers);
}

To implement this yourself, you have to write some unsafe code. Vec::swap is implemented like this:

fn swap(&mut self, a: usize, b: usize) {
    unsafe {
        // Can't take two mutable loans from one vector, so instead just cast
        // them to their raw pointers to do the swap
        let pa: *mut T = &mut self[a];
        let pb: *mut T = &mut self[b];
        ptr::swap(pa, pb);
    }
}

It takes two raw pointers from the vector and uses ptr::swap to swap them safely.

There is also a mem::swap(&mut T, &mut T) when you need to swap two distinct variables. That cannot be used here because Rust won't allow taking two mutable borrows from the same vector.


As mentioned by @gsingh2011, the accepted answer is no longer good approach. With current Rust this code works fine:

fn main() {
    let mut numbers = vec![1, 2, 3];
    println!("before = {:?}", numbers);
    numbers.swap(0, 2);
    println!("after = {:?}", numbers);
}

try it here