'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 |
