Programmation réactive en Rust : bibliothèques, frameworks et exemples pratiques

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Programmation réactive en Rust : aperçu des outils et exemples de code



La programmation réactive est un paradigme orienté vers les flux de données asynchrones et la propagation des changements. Dans l'écosystème Rust, elle est implémentée via des bibliothèques puissantes telles que RxRust (Reactive Extensions), futures-rs et async-std. Ces outils permettent de construire des systèmes élégants, tolérants aux pannes et hautes performances, des applications GUI aux services réseau. Dans cet article, nous analyserons les concepts clés, montrerons des exemples pratiques et vous aiderons à choisir la bibliothèque adaptée à votre projet Rust.



Bibliothèques principales pour la programmation réactive en Rust



Les bibliothèques les plus populaires pour la programmation réactive en Rust incluent :

  • RxRust — port de ReactiveX (Rx). Fournit Observable, Observer, les opérateurs map, filter, merge et autres. Idéal pour le traitement d'événements et de flux de données.
  • futures-rs — bibliothèque de base pour les calculs asynchrones. Inclut Stream, Future, Sink. Elle est à la base de nombreux systèmes réactifs.
  • async-std — bibliothèque standard asynchrone. Fournit des versions async des entrées-sorties fichiers, des opérations réseau et des canaux (channels) pour les flux réactifs.
  • tokio — runtime asynchrone avec support du multithreading. Souvent utilisé en combinaison avec futures-rs pour construire des applications réseau réactives.


Exemple 1 : Utilisation de RxRust pour le traitement d'événements

RxRust permet de créer des Observable à partir d'itérateurs, d'événements ou de sources asynchrones. Ci-dessous, un exemple simple de génération de nombres, de filtrage et d'abonnement au flux :



use rxrust::prelude::*;

fn main() { // Création d'un Observable à partir d'une plage de nombres observable::from_iter(1..10) .filter(|x| x % 2 == 0) // On garde uniquement les pairs .map(|x| x * 10) // Multiplication par 10 .subscribe( |x| println!("Reçu : {}", x), |err| eprintln!("Erreur : {}", err), || println!("Flux terminé"), );}


Résultat de l'exécution :

Reçu : 20Reçu : 40Reçu : 60Reçu : 80Flux terminé


Exemple 2 : Flux asynchrones avec futures-rs

La bibliothèque futures-rs fournit le trait Stream, qui est l'équivalent asynchrone de Iterator. L'exemple suivant montre la création d'un flux, sa transformation et la collecte des résultats :



use futures::stream::{self, StreamExt};

#[tokio::main]async fn main() { let stream = stream::iter(1..=5) .map(|x| x * x) .filter(|x| futures::future::ready(x % 2 == 0));

let results: Vec<i32> = stream.collect().await; println!("Carrés des nombres pairs : {:?}", results);}


Sortie :

Carrés des nombres pairs : [4, 16]


Exemple 3 : Canaux réactifs dans async-std

Les canaux (channels) sont la base des systèmes réactifs. La bibliothèque async-std fournit des canaux multi-utilisateurs qui peuvent être utilisés pour transmettre des événements entre tâches :



use async_std::sync::channel;use async_std::task;

fn main() { let (sender, receiver) = channel::unbounded::<String>();

// Tâche émettrice task::spawn(async move { sender.send("Bonjour".to_string()).await.unwrap(); sender.send("Monde".to_string()).await.unwrap(); });

// Tâche réceptrice (écouteur réactif) task::block_on(async { while let Some(msg) = receiver.recv().await { println!("Message reçu : {}", msg); } });}


Ce motif est à la base de l'architecture des applications orientées événements en Rust.



Comparaison des bibliothèques et recommandations

Recommendations