Как заменить две переменные?

Каков ближайший эквивалентный код Rust на этот код Python?

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

Я пытаюсь написать итеративную функцию Фибоначчи. У меня есть код Python, который я хочу преобразовать в Rust. Все в порядке, за исключением части подкачки.

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

Ответ 1

При замене переменных наиболее вероятно, что вам нужно создать новые привязки для a и b.

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

Тем не менее, в вашем конкретном случае, нет хорошего решения. Когда вы делаете, как указано выше, вы всегда создаете новые привязки для a и b, но вы хотите изменить существующие привязки. Одно из известных мне решений заключается в использовании временного:

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
}

Вы также можете сделать так, чтобы вы мутировали кортеж:

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
}

Вы также можете быть заинтересованы в обмене содержимого двух частей памяти. 99+% времени, вы хотите повторно связать переменные, но очень небольшое количество времени вы хотите изменить вещи "на месте":

fn main() {
    let (mut a, mut b) = (1, 2);
    std::mem::swap(&mut a, &mut b);

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

Обратите внимание, что это не лаконично, чтобы сделать этот обмен и добавить значения вместе в один шаг.

Смотрите также:

Ответ 2

Кроме того, лучший способ реализовать последовательность Фибоначчи в Rust использует 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<_>>());
}

См. раздел Язык программирования ржавчины глава об итераторах.