Programação Funcional em Rust: Técnicas Avançadas e Idiomas

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: Nível Avançado

\n\n

Rust é uma linguagem multiparadigma que combina organicamente estilos imperativo, orientado a objetos e funcional. Em nível avançado, a programação funcional em Rust permite escrever código mais seguro, expressivo e conciso. Neste artigo, vamos explorar conceitos-chave: closures com captura de ambiente, iteradores avançados, functores e mônadas usando Option e Result, além de currying e composição de funções.

\n\n

1. Closures: Propriedade, Empréstimo e Mutabilidade

\n\n

Closures em Rust não são apenas funções anônimas. Elas podem capturar variáveis do escopo circundante de três maneiras: por referência (&T), por referência mutável (&mut T) e por valor (T). O compilador escolhe automaticamente a trait menos restritiva: Fn, FnMut ou FnOnce.

\n\n

Veja um exemplo com captura por valor e uso de move:

\n\n
fn main() {\n    let data = vec![1, 2, 3];\n    \n    // Captura por valor (move) — a propriedade é transferida para a closure\n    let closure = move || {\n        println!("{:?}", data);\n        // data não está mais disponível na função principal\n    };\n    \n    closure();\n    // println!("{:?}", data); // Erro: data foi movida\n}\n
\n\n

Uma técnica avançada é usar closures para criar fábricas de funções:

\n\n
fn make_multiplier(factor: i32) -> impl Fn(i32) -> i32 {\n    move |x| x * factor\n}\n\nfn main() {\n    let double = make_multiplier(2);\n    let triple = make_multiplier(3);\n    \n    println!("{}", double(5));  // 10\n    println!("{}", triple(5));  // 15\n}\n
\n\n

Aqui, impl Fn(i32) -> i32 é o tipo de retorno da closure. Rust gera automaticamente um tipo anônimo que implementa a trait Fn.

\n\n

2. Iteradores Avançados: Cadeias, Adaptadores e Computação Preguiçosa

\n\n

Iteradores em Rust são uma ferramenta poderosa do estilo funcional. Eles são preguiçosos: os cálculos ocorrem apenas quando um método terminal é chamado (collect, for_each, fold, etc.).

\n\n

Veja um pipeline complexo de processamento de dados:

\n\n
fn process_data(data: Vec<i32>) -> Vec<i32> {\n    data.iter()\n        .filter(|&x| x > 0)                     // Mantém apenas positivos\n        .map(|x| x * 2)                          // Dobra\n        .enumerate()                             // Adiciona índices\n        .filter(|(i, _)| i % 2 == 0)             // Índices pares\n        .map(|(_, x)| x)                         // Extrai o valor\n        .collect()                               // Método terminal\n}\n
\n\n

Uma técnica avançada é usar flat_map para trabalhar com estruturas aninhadas e fold para acumulação:

\n\n
fn main() {\n    let nested = vec![vec![1, 2], vec![3, 4, 5], vec![6]];\n    \n    let flattened: Vec<i32> = nested.iter()\n        .flat_map(|v| v.iter())\n        .copied()\n        .collect();\n    \n    println!("{:?}", flattened); // [1, 2, 3, 4, 5, 6]\n    \n    // fold — análogo funcional ao reduce\n    let sum = flattened.iter()\n        .fold(0, |acc, x| acc + x);\n    \n    println!("Soma: {}", sum); // 21\n}\n
\n\n

É importante lembrar: cadeias de iteradores não criam coleções intermediárias se collect não for chamado. Isso economiza memória e melhora o desempenho.

\n\n

3. Mônadas Option e Result: Tratamento Funcional de Erros

\n\n

Na programação funcional, Option e Result são mônadas. Elas permitem processar valores opcionais e erros em cadeia, sem a necessidade de match ou if let aninhados.

\n\n

Veja um cenário típico com verificações aninhadas:

\n\n


                
                

Blogs

Book Recommendations