'How to swap two variables?

What is the closest equivalent Rust code to this Python code?

a, b = 1, 2
a, b = b, a + b

I am trying to write an iterative Fibonacci function. I have Python code I want to convert to Rust. Everything is fine, except for the swap part.

def fibonacci(n):
    if n < 2:
        return n
    fibPrev = 1
    fib = 1
    for num in range(2, n):
        fibPrev, fib = fib, fib + fibPrev
    return fib


Solution 1:[1]

In addition, a better way to implement the Fibonacci sequence in Rust is using the Iterator trait:

// Iterator data structure
struct FibIter(u32, u32);

// Iterator initialization function
fn fib() -> FibIter {
    FibIter(0u32, 1u32)
}

// Iterator trait implementation
impl Iterator for FibIter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        *self = FibIter(self.1, self.1 + self.0);
        Some(self.0)
    }
}

fn main() {
    println!("{:?}", fib().take(15).collect::<Vec<_>>());
}

See The Rust Programming Language chapter on iterators.

Solution 2:[2]

I'm surprised none of the answers mention the XOR-swap:

fibPrev ^= fib;
fib ^= fibPrev;
fibPrev ^= fib;

This is a well-known way to swap two values without using a temporary variable or risking integer overflow.

Note that with modern optimizing compilers, in most cases it's better from performance standpoint to just use a temporary variable (see link in the comment by trentcl). There are, however, some use cases for the XOR-swap, the linked Wikipedia article provides a decent overview of its pros and cons.

Interestingly enough, if you were to implement a XOR-swap as a function in rust, you don't need to check if you're trying to swap a variable with itself (in which case you'll end up with it being set to zero due to the properties of a XOR operation). Compare swap implementations in rust:

fn swap(a: &mut i32, b: &mut i32) {
    *a ^= *b;
    *b ^= *a;
    *a ^= *b;
}

and C++:

void swap(int& a, int& b) {
    if (&a == &b) return; // Avoid swapping the variable with itself
    a ^= b;
    b ^= a;
    a ^= b;
}

If you try to call swap like this in rust:

let mut a = 42;
swap(&mut a, &mut a);

You will get a compilation error:

error[E0499]: cannot borrow `a` as mutable more than once at a time
  --> src/main.rs:27:18
   |
27 |     swap(&mut a, &mut a);
   |     ---- ------  ^^^^^^ second mutable borrow occurs here
   |     |    |
   |     |    first mutable borrow occurs here
   |     first borrow later used by call

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shepmaster
Solution 2