When swapping variables, the most likely thing you want is to create new bindings for a and b.
fn main() { let (a, b) = (1, 2); let (b, a) = (a, a + b); }
For your actual case, you want to modify the existing bindings. Rust 1.59 will stabilize destructuring assignment:
fn fibonacci(n: u64) -> u64 { if n < 2 { return n; } let mut fib_prev = 1; let mut fib = 1; for _ in 2..n { (fib_prev, fib) = (fib, fib + fib_prev); } fib }
Before Rust 1.59, you can use a temporary variable:
fn fibonacci(n: u64) -> u64 { if n < 2 { return n; } let mut fib_prev = 1; let mut fib = 1; for _ in 2..n { let next = fib + fib_prev; fib_prev = fib; fib = next; } fib }
You could also make it so that you mutate the tuple:
fn fibonacci(n: u64) -> u64 { if n < 2 { return n; } let mut fib = (1, 1); for _ in 2..n { fib = (fib.1, fib.0 + fib.1); } fib.1 }
You may also be interested in swapping the contents of two pieces of memory. 99+% of the time, you want to re-bind the variables, but a very small amount of time you want to change things "in place":
fn main() { let (mut a, mut b) = (1, 2); std::mem::swap(&mut a, &mut b); println!("{:?}", (a, b)); }
Note that it's not concise to do this swap and add the values together in one step.
For a very concise implementation of the Fibonacci sequence that returns an iterator:
fn fib() -> impl Iterator<Item = u128> { let mut state = [1, 1]; std::iter::from_fn(move || { state.swap(0, 1); let next = state.iter().sum(); Some(std::mem::replace(&mut state[1], next)) }) }
See also: