2017-07-14 1 views
0

Je ne comprends pas la mutabilité des itérateurs de Rust. Pour essayer de comprendre, je donne les résultats suivants:Pourquoi une boucle for ne nécessite-t-elle pas que l'itérateur soit modifiable?

struct Fibonacci { 
    curr: u32, 
    next: u32, 
} 

impl Iterator for Fibonacci { 
    type Item = u32; 

    fn next(&mut self) -> Option<u32> { 
     let new_next = self.curr + self.next; 
     self.curr = self.next; 
     self.next = new_next; 
     Some(self.curr) 
    } 
} 

fn fibonacci() -> Fibonacci { 
    Fibonacci { curr: 1, next: 1 } 
} 

fn main() { 
    let f: Fibonacci = fibonacci(); 
    for i in f.take(5) { 
     println!("> {}", i); 
    } 
} 

Très simplement, j'ai un itérateur personnalisé que je reviens à l'aide fibonacci. Maintenant, quand je crée ceci, la variable f est immuable. Que se passe-t-il dans la boucle for qui rend ce travail? La boucle for n'a-t-elle pas utilisé f mutably?

Répondre

1

La boucle for n'a-t-elle pas utilisé f mutably?

n ° take returns a new iterator. Mais même alors, for is syntactic sugar. Votre code se transforme en

let f: Fibonacci = fibonacci(); 

{ 
    let result = match IntoIterator::into_iter(f.take(5)) { 
     mut iter => { 
      loop { 
       match iter.next() { 
        Some(i) => { 
         println!("{}", i); 
        } 
        None => break, 
       } 
      } 
     } 
    }; 
    result 
} 

En raison de IntoIterator, nous avons jamais muter f ou f.take(5), mais seulement le résultat de into_iter.