💻 Exemplos: Capítulo 12: Coleções Padrão (Vec, HashMap, HashSet) e Iteradores Idiomáticos
💻 Exemplos: Capítulo 12: Coleções da Biblioteca Padrão e Iteradores
Especialização em Sistemas com Rust • Demonstrações Práticas Compiláveis
🎯 Objetivo dos Exemplos
Dominar as coleções fundamentais da biblioteca padrão do Rust (std::collections::HashMap, HashSet e Vec), a API declarativa de Iteradores com avaliação preguiçosa (lazy), mutação atômica de mapas com o padrão Entry API (.or_insert()) e combinadores funcionais (map, filter, fold, collect).
1. Código Fonte Completo (src/main.rs)
//! Coleções Padrão, Entry API e Programação Funcional com Iteradores em Rust
use std::collections::{HashMap, HashSet};
#[derive(Debug, PartialEq, Eq, Hash)]
struct RegistroEvento {
servico: String,
codigo_http: u16,
}
fn main() {
println!("=== COLEÇÕES PADRÃO E ITERADORES IDIOMÁTICOS ===");
// 1. Tabela Hash (HashMap) e o Idioma Entry API
println!("Contabilizando ocorrências de logs com HashMap e Entry API:");
let logs_recebidos = vec![
"AUTH_SUCCESS", "DB_TIMEOUT", "AUTH_SUCCESS",
"API_NOT_FOUND", "DB_TIMEOUT", "DB_TIMEOUT",
];
let mut contador_ocorrencias: HashMap<&str, u32> = HashMap::new();
for log in logs_recebidos {
// .entry(chave).or_insert(0) obtém uma referência mutável ao valor existente
// ou insere 0 caso não exista, permitindo incremento direto em uma única linha!
let contador = contador_ocorrencias.entry(log).or_insert(0);
*contador += 1;
}
for (tipo_log, contagem) in &contador_ocorrencias {
println!(" Log: {:<15} | Total de Ocorrências: {}", tipo_log, contagem);
}
// 2. Conjuntos Únicos com HashSet
println!("\nFiltrando IPs únicos de conexões suspeitas com HashSet:");
let acessos_brutos = vec![
"192.168.1.10", "10.0.0.5", "192.168.1.10",
"172.16.0.1", "10.0.0.5", "192.168.1.10",
];
let ips_unicos: HashSet<&str> = acessos_brutos.into_iter().collect();
println!("IPs únicos detectados (total {}): {:?}", ips_unicos.len(), ips_unicos);
// 3. Pipeline Funcional de Iteradores (Zero-Cost Abstractions)
println!("\nProcessando métricas de latência com adaptadores de iterador:");
let latencias_ms = vec![12, 45, 180, 22, 95, 310, 8, 140];
// Operações encadeadas são preguiçosas: nenhum processamento ocorre até o .collect() ou .fold()
let soma_latencias_criticas: u32 = latencias_ms
.iter()
.filter(|&&lat| lat > 50) // Filtra apenas requisições lentas (> 50ms)
.map(|&lat| lat * 2) // Aplica peso de penalidade dobrado
.fold(0, |acumulador, lat| acumulador + lat); // Reduz somando todos
println!("Soma ponderada das latências críticas (> 50ms * 2): {} ms", soma_latencias_criticas);
// 4. Criação de Vetor Filtrado e Mapeado com .collect()
let alertas_formatados: Vec<String> = latencias_ms
.iter()
.filter(|&&lat| lat > 100)
.map(|&lat| format!("ALERTA_LATENCIA_{}MS", lat))
.collect();
println!("Alertas gerados: {:?}", alertas_formatados);
// 5. Mutação de Coleção in-place com iter_mut()
let mut niveis_buffer = vec![100, 200, 300];
println!("\nValores antes de iter_mut(): {:?}", niveis_buffer);
for nivel in niveis_buffer.iter_mut() {
*nivel += 50; // Desreferenciação e mutação direta
}
println!("Valores após iter_mut(): {:?}", niveis_buffer);
}
2. Saída Esperada no Terminal
=== COLEÇÕES PADRÃO E ITERADORES IDIOMÁTICOS ===
Contabilizando ocorrências de logs com HashMap e Entry API:
Log: AUTH_SUCCESS | Total de Ocorrências: 2
Log: API_NOT_FOUND | Total de Ocorrências: 1
Log: DB_TIMEOUT | Total de Ocorrências: 3
Filtrando IPs únicos de conexões suspeitas com HashSet:
IPs únicos detectados (total 3): {"172.16.0.1", "10.0.0.5", "192.168.1.10"}
Processando métricas de latência com adaptadores de iterador:
Soma ponderada das latências críticas (> 50ms * 2): 1450 ms
Alertas gerados: ["ALERTA_LATENCIA_180MS", "ALERTA_LATENCIA_310MS", "ALERTA_LATENCIA_140MS"]
Valores antes de iter_mut(): [100, 200, 300]
Valores após iter_mut(): [150, 250, 350]