Programação Funcional em Rust: Abordagens e Exemplos

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

Introdução à programação funcional em Rust

Rust é uma linguagem multiparadigma que, juntamente com os estilos imperativo e orientado a objetos, suporta ativamente a programação funcional. Recursos integrados, como closures, iteradores, um sistema de tipos poderoso e imutabilidade por padrão, permitem escrever código conciso, seguro e expressivo. Neste artigo, vamos explorar os conceitos-chave da abordagem funcional em Rust e mostrar como aplicá-los na prática.



Fundamentos da abordagem funcional: imutabilidade e funções puras

A programação funcional é construída sobre dois pilares: imutabilidade de dados e funções puras. Rust incentiva a imutabilidade — por padrão, todas as variáveis são imutáveis. Para alterar um valor, é necessário especificar explicitamente mut.

fn main() {    let x = 5; // variável imutável    // x = 6; // erro de compilação    let mut y = 10;    y += 5; // permitido, pois y é mutável    println!("x = {}, y = {}", x, y);}

Uma função pura não tem efeitos colaterais e sempre retorna o mesmo resultado para os mesmos argumentos. Rust permite escrever tais funções, mas não obriga a isso — você pode misturar estilos livremente.

fn add(a: i32, b: i32) -> i32 {    a + b // função pura}


Closures — funções anônimas

Closures em Rust são funções anônimas que podem capturar variáveis do escopo circundante. Elas são definidas com a sintaxe |parâmetros| corpo. As closures são de três tipos, dependendo da forma de captura: por referência (&T), por referência mutável (&mut T) e por valor (T).

Exemplo simples de closure

fn main() {    let factor = 2;    let multiply = |x: i32| x * factor;    println!("{}", multiply(10)); // 20}

Closure com captura mutável

fn main() {    let mut counter = 0;    let mut increment = || {        counter += 1;        counter    };    println!("{}", increment()); // 1    println!("{}", increment()); // 2}

Closures são amplamente utilizadas com iteradores e para passar comportamentos para funções de ordem superior.



Iteradores e cadeias funcionais

Iteradores em Rust são uma das abstrações funcionais mais poderosas. Em vez de loops, você pode construir cadeias de métodos como map, filter, fold e outros. Os iteradores são preguiçosos — os cálculos ocorrem apenas quando um consumidor é chamado (por exemplo, collect ou for_each).

Exemplo: filtragem e transformação

fn main() {    let numbers = vec![1, 2, 3, 4, 5, 6];    let result: Vec<i32> = numbers        .iter()        .filter(|&x| x % 2 == 0) // mantém os pares        .map(|x| x * x)          // eleva ao quadrado        .collect();    println!("{:?}", result); // [4, 16, 36]}

Fold — acumulação de valores

fn main() {    let numbers = vec![1, 2, 3, 4];    let sum = numbers.iter().fold(0, |acc, x| acc + x);    println!("Soma: {}", sum); // 10}

Iteradores tornam o código declarativo: você descreve o que precisa ser feito, não como. Isso reduz a probabilidade de erros e melhora a legibilidade.



Pattern matching

A construção match é um elemento central do estilo funcional em Rust. Ela permite desestruturar estruturas de dados complexas, lidar com variantes de Option e Result e escrever verificações exaustivas.

Exemplo básico

fn describe_number(n: i32) -> &'static str {    match n {        0 => "zero",        1 | 2 => "número pequeno",        3..=10 => "número médio",        _ if n < 0 => "negativo",        _ => "número grande"    }}

Blogs

Book Recommendations