Iteradors en Rust: Els nombres de Lucas

Lectura de 2 minuts Publicat el 2021-07-16

Com implementar un iterador en Rust per generar la sèrie de Lucas

2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 123...

La finalitat d'aquest article és ensenyar com implementar un iterador en Rust, per això he decidit implementar la sèrie de Lucas, aquesta sèrie està íntimament relacionada amb els nombres Fibonacci, per exemple:

Sumar dos nombres Fibonacci separats per dos termes resulta en el nombre Lucas entre aquests.

Implementar l'estructura de dades

La sèrie de Lucas comença amb els valors 2 i 1 per a n = 0 i n = 1:

La sèrie de Lucas

struct SerieLucas {
    a: u64,
    b: u64,
}

// En Rust es defineixen constructors sense paràmetres implementant Default.
impl Default for SerieLucas {
    fn default() -> Self {
        Self {
            a: 2,
            b: 1
        }
    }
}

Aquí a representa Ln-1 i b Ln-2.

Per a implementar un iterador, s'ha d’implementar el trait std::iter::Iterator.

Per fer això s'ha de fer el següent:

use std::iter::Iterator; // Important!

// ...

impl Iterator for SerieLucas {
    type Item = u64;

    fn next(&mut self) -> Option<Self::Item> {
        let r = self.a;
        self.a = self.b;
        self.b += r;
        Some(r)
    }
}

Com que és una sèrie infinita, mai es retorna None.

Un exemple de com utilitzar l'Iterador:

fn main() {
    let serie = SerieLucas::default();

    let valors: Vec<u64> = serie.take(20).collect();

    println!("{:?}", valors);
}

Que emet el següent per la consola:

[2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 123, 199, 322, 521, 843, 1364, 2207, 3571, 5778, 9349]