3

I'm trying to swap two integers in Rust without any library.

fn main() {
    let mut a = 5;
    let mut b = 6;
    swap(&mut a, &mut b);
    println!("{}, {}", a, b); // expecting 6, 5
}

First I've tried:

fn swap(mut a: &mut u32, mut b: &mut u32) {
    (a, b) = (b, a); // destructuring assignments are not currently supported
}

Then:

fn swap(mut a: &mut u32, mut b: &mut u32) {
    let temp = a;
    a = b;
    b = temp;
}
// got error[E0623]: lifetime mismatch

Finally:

fn swap<'a>(mut a: &'a mut u32, mut b: &'a mut u32) {
    let temp = a;
    a = b;
    b = temp;
}
// still does not work; when this scope ends a and b in `main()` are still 5 and 6 respectively
// got warning: value assigned to `a` is never read (for `b` as well)

I don't know what's wrong; last implementation looks cumbersome to me but I think it should work as I am passing mutable reference to function, but it does not work.

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
109149
  • 1,223
  • 1
  • 8
  • 24
  • 2
    You are assigning the references, not the referred to values. Try `temp=*a` and so on. – prog-fh Oct 12 '20 at 15:19
  • Duplicate of [How to swap two variables?](https://stackoverflow.com/questions/31798737/how-to-swap-two-variables) – Herohtar Oct 13 '20 at 04:44

3 Answers3

7

The efficient way:

use std::mem;

let mut x = 5;
let mut y = 42;

mem::swap(&mut x, &mut y);

assert_eq!(42, x);
assert_eq!(5, y);

https://doc.rust-lang.org/std/mem/fn.swap.html

C14L
  • 12,153
  • 4
  • 39
  • 52
4

You can dereference references:

fn swap(a: &mut u32, b: &mut u32) {
    let t: u32 = *a; // Read the integer with `*a`
    *a = *b; // Write to the reference with `*a = <stuff>`
    *b = t;
}

fn main() {
    let mut a = 6;
    let mut b = 7;
    
    println!("{}, {}", a, b);
    swap(&mut a, &mut b);
    println!("{}, {}", a, b);
}

Output:

6, 7
7, 6

Playground

ForceBru
  • 43,482
  • 10
  • 63
  • 98
2

For copyable types this is quite succinct (if you prefer not to use std::mem::swap:

fn swap<T: Copy>(a: T, b: T) -> (T, T) {
    (b, a)
}

fn main() {
    let (a, b) = (1, 2);
    let (a, b) = swap(a, b);

    println!("A: {}, B: {}", a, b);

    // Note you can also just do this
    let (a, b) = (b, a);

    println!("A: {}, B: {}", a, b);
}
Martin Gallagher
  • 4,444
  • 2
  • 28
  • 26
  • I don't really see the point of this answer. Swapping two variables only makes sense if you actually mutate existing variables. This creates two new variables which happen to have swapped names, but it doesn't mutate any existing variables. Instead of doing this, you can also just swap the names in the remainder of the function. – Sven Marnach Oct 12 '20 at 18:09