Programação Funcional em Rust: Expressões e Práticas

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 Funcional em Rust: De Iteradores a Mônadas

Rust é uma linguagem multiparadigma que combina perfeitamente estilos imperativos, orientados a objetos e funcionais. Apesar de Rust não ser uma linguagem puramente funcional (como Haskell), seu sistema de tipos e modelo de propriedade permitem escrever código elegante, seguro e expressivo em estilo funcional. Neste artigo, vamos detalhar os conceitos-chave da programação funcional (PF) em Rust: closures, iteradores, pattern matching e trabalho com Option e Result. Este material será útil tanto para iniciantes quanto para desenvolvedores experientes que desejam aprofundar sua compreensão das capacidades funcionais do Rust.



Closures e Expressões Lambda

Closures em Rust são funções anônimas que podem capturar variáveis do escopo ao redor. Elas são a base da abordagem funcional, permitindo que comportamentos sejam passados como dados.

A sintaxe para closures é concisa: |parâmetros| corpo. Closures podem ser passadas para funções, armazenadas em variáveis e retornadas de funções. É importante lembrar das três traits que controlam a captura: Fn (empréstimo), FnMut (empréstimo mutável) e FnOnce (consumo).

fn main() {    // Closure simples    let add_one = |x: i32| x + 1;    println!("{}", add_one(5)); // 6

// Capturando uma variável let factor = 10; let multiply = |x| x * factor; println!("{}", multiply(3)); // 30

// Closure com trait FnOnce let name = String::from("Rust"); let greet = move || { println!("Olá, {}!", name); // name é movido }; greet(); // println!("{}", name); // Erro! name não está mais disponível}

A palavra-chave move força a captura por valor (movimento), o que é frequentemente necessário ao trabalhar com multithreading ou ao passar uma closure para outro contexto.



Iteradores: Processamento Preguiçoso e Encadeamento de Métodos

Um dos aspectos mais fortes do estilo funcional em Rust é o poderoso adaptador de iteradores. Em vez de loops for explícitos e mutação de variáveis, você usa encadeamento de métodos: map, filter, fold, collect e outros. Iteradores em Rust são preguiçosos — eles não realizam computações até que um método consumidor seja chamado (ex.: collect() ou for_each()).

fn main() {    let numbers = vec![1, 2, 3, 4, 5, 6];

// Abordagem funcional: filtragem e transformação let result: Vec<i32> = numbers .iter() // cria um iterador .filter(|&x| x % 2 == 0) // mantém apenas números pares .map(|x| x * x) // eleva ao quadrado .collect(); // coleta em um vetor

println!("{:?}", result); // [4, 16, 36]

// Soma usando fold (redução) let sum = numbers.iter().fold(0, |acc, x| acc + x); println!("Soma: {}", sum); // 21

// Verificação de condição com any e all let has_even = numbers.iter().any(|x| x % 2 == 0); println!("Tem números pares: {}", has_even); // true}

Usar iteradores torna o código declarativo, legível e menos propenso a erros relacionados a indexação e limites de array. O compilador Rust frequentemente otimiza cadeias de iteradores em código de máquina eficiente, comparável a loops manuais.



Pattern Matching e Desestruturação

Pattern matching (match) é o coração do controle de fluxo funcional em Rust. Ele permite tratar com segurança todas as variantes possíveis de dados, especialmente em combinação com tipos de dados algébricos (enum). Padrões podem ser aninhados, incluir guards e desestruturar structs, tuplas e enums.

enum Message {    Quit,    Move { x: i32, y: i32 },    Write(String),    ChangeColor(i32, i32, i32),}

fn handle_

Blogs

Book Recommendations