💻 Exemplos: Capítulo 14: Closures, Functores e Programação Funcional
💻 Exemplos: Capítulo 14: Closures, Captura de Ambiente e Programação Funcional
Especialização em Sistemas com Rust • Demonstrações Práticas Compiláveis
🎯 Objetivo dos Exemplos
Apresentar a sintaxe e a semântica de Closures em Rust, as 3 traits de chamada do compilador (Fn, FnMut e FnOnce), a palavra-chave move para transferir o ownership de variáveis capturadas e a construção de funções de alta ordem personalizadas.
1. Código Fonte Completo (src/main.rs)
//! Closures, Traits de Captura (Fn, FnMut, FnOnce) e Higher-Order Functions
/// Função de Alta Ordem (Higher-Order Function)
/// Recebe uma closure genérica F que implementa o trait Fn(i32) -> i32
fn aplicar_transformacao<F>(valor: i32, transformador: F) -> i32
where
F: Fn(i32) -> i32,
{
transformador(valor)
}
/// Recebe uma closure que muta seu próprio ambiente interno (FnMut)
fn executar_acumulador_n_vezes<F>(mut acumulador: F, iteracoes: usize)
where
F: FnMut(usize),
{
for i in 1..=iteracoes {
acumulador(i);
}
}
/// Recebe uma closure que consome a si mesma (FnOnce)
fn executar_e_destruir<F>(operacao: F)
where
F: FnOnce() -> String,
{
let resultado = operacao();
println!(" Resultado da closure FnOnce: '{}'", resultado);
}
fn main() {
println!("=== CLOSURES E PROGRAMAÇÃO FUNCIONAL EM RUST ===");
// 1. Closure básica com inferência de tipos
let multiplicador_base = 10;
// Captura 'multiplicador_base' por referência imutável (&) -> Implementa 'Fn'
let calcular_fator = |x: i32| x * multiplicador_base;
let res = aplicar_transformacao(5, calcular_fator);
println!("Resultado da transformação via Fn: {}", res);
println!("Multiplicador base continua acessível: {}", multiplicador_base);
// 2. Closure com mutação do ambiente capturado (FnMut)
let mut total_bytes_processados = 0;
println!("\nIniciando acumulador mutável com FnMut:");
let mut registrar_bloco = |indice: usize| {
let bytes_bloco = indice * 64;
total_bytes_processados += bytes_bloco;
println!(" Passo {}: +{} bytes adicionados (Total acumulado: {})", indice, bytes_bloco, total_bytes_processados);
};
executar_acumulador_n_vezes(&mut registrar_bloco, 3);
println!("Total consolidado após FnMut: {} bytes", total_bytes_processados);
// 3. A palavra-chave 'move' (Transferindo Ownership para a Closure)
let dados_criticos = String::from("CHAVE_CRIPTOGRAFICA_MESTRE");
// 'move' força a transferência do ownership de 'dados_criticos' para dentro da closure
let closure_proprietaria = move || {
format!("Cifra processada com base em: [{}]", dados_criticos)
// 'dados_criticos' é consumido e destruído aqui
};
// 'dados_criticos' não pode mais ser lida na main!
// println!("{}", dados_criticos); // ERRO: value borrowed here after move
executar_e_destruir(closure_proprietaria);
// 4. Combinando Closures com Iteradores Nativos
println!("\nFiltrando e mapeando eventos de telemetria:");
let leituras = vec![12.5, 45.0, 88.2, 105.4, 23.1, 99.9];
let leituras_anormais: Vec<f64> = leituras
.into_iter()
.filter(|&pressao| pressao > 80.0)
.map(|pressao| (pressao * 1.1).round())
.collect();
println!("Leituras anormais corrigidas (+10%): {:?}", leituras_anormais);
}
2. Saída Esperada no Terminal
=== CLOSURES E PROGRAMAÇÃO FUNCIONAL EM RUST ===
Resultado da transformação via Fn: 50
Multiplicador base continua acessível: 10
Iniciando acumulador mutável com FnMut:
Passo 1: +64 bytes adicionados (Total acumulado: 64)
Passo 2: +128 bytes adicionados (Total acumulado: 192)
Passo 3: +192 bytes adicionados (Total acumulado: 384)
Total consolidado após FnMut: 384 bytes
Resultado da closure FnOnce: 'Cifra processada com base em: [CHAVE_CRIPTOGRAFICA_MESTRE]'
Filtrando e mapeando eventos de telemetria:
Leituras anormais corrigidas (+10%): [97.0, 116.0, 110.0]