Programação Reativa em Rust: bibliotecas, frameworks e exemplos práticos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Programação Reativa em Rust: visão geral das ferramentas e exemplos de código



Programação reativa é um paradigma orientado a fluxos de dados assíncronos e propagação de mudanças. No ecossistema Rust, ela é implementada através de bibliotecas poderosas, como RxRust (Reactive Extensions), futures-rs e async-std. Essas ferramentas permitem construir sistemas elegantes, tolerantes a falhas e de alto desempenho, desde aplicações GUI até serviços de rede. Neste artigo, abordaremos os conceitos-chave, mostraremos exemplos práticos e ajudaremos você a escolher a biblioteca adequada para seu projeto em Rust.



Principais bibliotecas para programação reativa em Rust



As bibliotecas mais populares para programação reativa em Rust incluem:

  • RxRust — porta do ReactiveX (Rx). Fornece Observable, Observer, operadores map, filter, merge e outros. Ideal para tratamento de eventos e fluxos de dados.
  • futures-rs — biblioteca base para computação assíncrona. Inclui Stream, Future, Sink. Está na base de muitos sistemas reativos.
  • async-std — biblioteca padrão assíncrona. Fornece versões assíncronas de E/S de arquivos, operações de rede e canais (channels) para fluxos reativos.
  • tokio — runtime assíncrono com suporte a multithreading. Frequentemente usado em conjunto com futures-rs para construir aplicações de rede reativas.


Exemplo 1: Usando RxRust para tratamento de eventos

RxRust permite criar Observable a partir de iteradores, eventos ou fontes assíncronas. Abaixo, um exemplo simples de geração de números, filtragem e inscrição no fluxo:



use rxrust::prelude::*;

fn main() { // Criando um Observable a partir de um intervalo de números observable::from_iter(1..10) .filter(|x| x % 2 == 0) // Mantendo apenas os pares .map(|x| x * 10) // Multiplicando por 10 .subscribe( |x| println!("Recebido: {}", x), |err| eprintln!("Erro: {}", err), || println!("Fluxo concluído"), );}


Resultado da execução:

Recebido: 20Recebido: 40Recebido: 60Recebido: 80Fluxo concluído


Exemplo 2: Fluxos assíncronos com futures-rs

A biblioteca futures-rs fornece o trait Stream, que é o análogo assíncrono de Iterator. O exemplo a seguir demonstra a criação de um fluxo, sua transformação e coleta de resultados:



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!("Quadrados dos números pares: {:?}", results);}


Saída:

Quadrados dos números pares: [4, 16]


Exemplo 3: Canais reativos em async-std

Canais (channels) são a base dos sistemas reativos. A biblioteca async-std fornece canais multiprodutores que podem ser usados para transmitir eventos entre tarefas:



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

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

// Tarefa remetente task::spawn(async move { sender.send("Olá".to_string()).await.unwrap(); sender.send("Mundo".to_string()).await.unwrap(); });

// Tarefa receptora (ouvinte reativo) task::block_on(async { while let Some(msg) = receiver.recv().await { println!("Mensagem recebida: {}", msg); } });}


Este padrão está na base da arquitetura de aplicações orientadas a eventos em Rust.



Comparação de bibliotecas e recomendações

Recommendations