2015-08-04 28 views
7

Qual è il codice Rust equivalente più simile a questo codice Python?Come scambiare due variabili?

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

Sto provando a scrivere una funzione di Fibonacci iterativa. Ho il codice Python che voglio convertire in Rust. Va tutto bene, tranne per la parte swap.

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 
+0

Assicurati di leggere [* The Rust Programming Language *] (http://doc.rust-lang.org/stable/book/). Riguarda molti argomenti introduttivi. – Shepmaster

+1

@Shepmaster, ha trascorso un po 'di tempo a leggere su [swap] (http://doc.rust-lang.org/std/mem/fn.swap.html) e [sostituire] (http: //doc.rust-lang. org/std/mem/fn.replace.html) ma non sono sicuro di cosa ho bisogno qui. –

risposta

14

Quando scambiando variabili, la cosa più probabile è che si desidera creare nuovi attacchi per a e b.

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

Tuttavia, nel tuo caso, non c'è una soluzione piacevole. Quando si fa come sopra, si creano sempre nuovi collegamenti per a e b, ma si desidera modificare i collegamenti esistenti. Una soluzione che conosco è quello di utilizzare una temporanea:

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 
} 

Si potrebbe anche fare in modo che si 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 
} 

Si può anche essere interessati a scambiare il contenuto di due pezzi di memoria. 99 +% del tempo, si vuole ri-legare le variabili, ma una piccola quantità di tempo che si desidera cambiare le cose "a posto":

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

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

Nota che non è concisa fare questo swap e aggiungi i valori insieme in un unico passaggio.

+0

puoi approfondire quando qualcuno vorrebbe cambiare le cose sul posto e re-legare le variabili? Inoltre, cosa c'è di sbagliato nella creazione di nuovi binding? Non efficiente? –

6

Inoltre, un modo migliore per implementare la sequenza di Fibonacci a Rust sta usando il Iterator tratto:

// 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<_>>()); 
} 

Vedi la ruggine Programming Languagechapter on iterators.