2015-08-04 13 views
7

Jaki jest najbliższy odpowiednik kodu Rust kodu tego Pythona?Jak zamienić dwie zmienne?

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

Próbuję napisać funkcję iteracyjną Fibonacciego. Mam kod Pythona, który chcę przekonwertować na Rust. Wszystko jest w porządku, z wyjątkiem części zamiennej.

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

Proszę przeczytać [* The Rust Programming Language *] (http://doc.rust-lang.org/stable/book/). Obejmuje wiele tematów wprowadzających. – Shepmaster

+1

@Shepmaster, spędził trochę czasu czytając o [swap] (http://doc.rust-lang.org/std/mem/fn.swap.html) i [replace] (http: //doc.rust-lang. org/std/mem/fn.replace.html), ale nie jestem pewien, czy tego potrzebuję. –

Odpowiedz

14

Kiedy zamiana zmiennych, najbardziej prawdopodobną rzeczą, którą chcesz jest stworzenie nowych powiązania dla a i b.

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

Jednak w twoim przypadku nie ma dobrego rozwiązania. Gdy wykonasz powyższe czynności, zawsze tworzysz nowe wiązania dla a i b, ale chcesz zmodyfikować istniejące powiązania. Jednym z rozwiązań wiem jest użycie tymczasowej:

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 
} 

Można też zrobić to tak, że mutują krotki:

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 
} 

Możesz być także zainteresowany zamiana zawartości dwóch kawałków pamięć. 99 +% czasu, chcesz ponownie powiązać zmienne, ale bardzo niewielką ilość czasu, którą chcesz zmienić ten stan rzeczy „na miejscu”:

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

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

pamiętać, że to nie jest zwięzły, aby to zrobić swap oraz dodaj wartości razem w jednym kroku.

+0

Czy możesz opracować, kiedy ktoś chciałby zmienić rzeczy zamiast ponownego wiązania zmiennych? Co jest złego w tworzeniu nowych powiązań? Nie jest wydajny? –

6

Ponadto lepszym sposobem wdrożenia ciągu Fibonacciego w Rust wykorzystuje cechę Iterator:

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

Zobacz Rust Programming Languagechapter on iterators.