diff --git a/iterators.md b/iterators.md index bb85b45a1c8a4bc898ee7ef59f931b5a9a1f80bd..ba40d4e2b4c99d9b93073dffb6d4f1adc1dfb257 100644 --- a/iterators.md +++ b/iterators.md @@ -5,7 +5,113 @@ author: Orestis Malaspinas sansfont: Sans Serif --- -# Itérateurs +# Parcourir une liste -Under construction +## Boucles `for`{.rust} (1/3) +On a déjà vu différentes façon de parcourir des collections: + +1. La boucle `for`{.rust} sur un `Range`{.rust} + + ```{.lang-rust} + let x = vec![1, 2, 3]; + for i in 0..3 { // Range + println!("{}", x[i]); + } + ``` +2. La boucle `for`{.rust} directement sur le vecteur + + ```{.lang-rust} + let x = vec![1, 2, 3]; + for i in x { // Vec + println!("{}", i); + } + ``` + +## Boucles `for`{.rust} (2/3) + +- La syntaxe générale est + + ```{.lang-rust} + for variable in expression { + // do something + } + ``` +- `expression`{.rust} est un **itérateur**: une série d'éléments. +- `variable`{.rust} prend à tour de rôle la valeur de chaque élément de l'itérateur. +- `variable`{.rust} peut être utilisé dans le bloc `for`{.rust}. + +## Boucles `for`{.rust} (3/3) + +Sans itérateurs on écrirait quelque chose du genre + +```{.lang-rust} +let mut i = 0; +let x = vec![1, 2, 3]; +while i < 3 { + println!("{}", x[i]); + i += 1; +} +``` + +# Les itérateurs + +## Généralités + +- Un **itérateur** est un objet sur lequel on peut appeler la méthode `.next()`{.rust}. +- La méthode `.next()`{.rust} est dans le trait `Iterator`. +- Lorsque `.next()`{.rust} est appelé l'itérateur retourne la prochaine valeur. +- Il se met dans l'état "suivant": il est **modifié**. +- `.next()`{.rust} retourne une `Option<T>`{.rust}. + +<pre><code data-trim="hljs rust" class="lang-rust"> +fn main() { + let mut r = 0..3; + + println!("{:?}", r.next()); // retourne? + println!("{:?}", r.next()); // retourne? + println!("{:?}", r.next()); // retourne? + println!("{:?}", r.next()); // retourne? + println!("{:?}", r.next()); // retourne? +} +</code></pre> + +## Implémentation d'un itérateur + +- La suite de Fibonacci: + +$$ +{\mathcal {F}}_{n+2}={\mathcal {F}}_{n+1}+{\mathcal {F}}_{n} +$$ + +<pre><code data-trim="hljs rust" class="lang-rust"> +#[derive(Debug)] +struct Fib { + act: usize, // nombre actuel + prec: usize, // nombre précédent +} + +impl Iterator for Fib { + type Item = usize; // type de retour de l'itérateur + + fn next(&mut self) -> Option<usize> { // next retourne une option + let new_act = self.act + self.prec; + + self.prec = self.act; + self.act = new_act; + + Some(self.act) // la suite de Fibonacci est infinie, donc on retourne jamais None + } +} + +fn main() { + let mut fib = Fib{act: 1, prec: 1}; + println!("{:?}", fib.next()); + + let fib4 = fib.take(4); // retourne les 4 prochains éléments de l'itérateur + + for i in fib4 { + println!("{}", i); + } +} +</code></pre> \ No newline at end of file