💻 Exemplos: Capítulo 13: Traits, Trait Bounds, Derives e Generics
💻 Exemplos: Capítulo 13: Traits, Generics e Polimorfismo Estático
Especialização em Sistemas com Rust • Demonstrações Práticas Compiláveis
🎯 Objetivo dos Exemplos
Demonstrar a criação de Traits (interfaces de comportamento), implementação para tipos customizados, funções genéricas parametrizadas com Trait Bounds (where T: Trait), polimorfismo em tempo de compilação (Monomorphization com custo zero de despacho dinâmico) e despacho dinâmico via Trait Objects (&dyn Trait).
1. Código Fonte Completo (src/main.rs)
//! Traits, Trait Bounds, Generics e Polimorfismo Estático vs Dinâmico
use std::fmt::Debug;
// 1. Definição de Trait com comportamento padrão opcional
pub trait DispositivoSerializavel {
fn obter_identificador(&self) -> &str;
fn serializar_para_wire(&self) -> Vec<u8>;
// Método com implementação padrão (default method)
fn exibir_sumario(&self) {
println!(" Dispositivo ID: '{}' (Serialização pronta)", self.obter_identificador());
}
}
// 2. Structs Concretas
#[derive(Debug, Clone)]
pub struct SensorTemperatura {
pub id: String,
pub temperatura_celsius: f32,
}
#[derive(Debug, Clone)]
pub struct AtuadorValvula {
pub id: String,
pub abertura_percentual: u8,
}
// 3. Implementações da Trait
impl DispositivoSerializavel for SensorTemperatura {
fn obter_identificador(&self) -> &str {
&self.id
}
fn serializar_para_wire(&self) -> Vec<u8> {
let bytes_temp = self.temperatura_celsius.to_be_bytes();
let mut buffer = Vec::new();
buffer.extend_from_slice(b"TEMP:");
buffer.extend_from_slice(&bytes_temp);
buffer
}
}
impl DispositivoSerializavel for AtuadorValvula {
fn obter_identificador(&self) -> &str {
&self.id
}
fn serializar_para_wire(&self) -> Vec<u8> {
vec![b'V', b'A', b'L', b'V', self.abertura_percentual]
}
}
// 4. Polimorfismo Estático (Static Dispatch via Monomorphization)
// O compilador gera cópias em código de máquina para cada tipo concreto T!
fn transmitir_estatico<T>(dispositivo: &T)
where
T: DispositivoSerializavel + Debug,
{
println!("\n[ESTÁTICO - Zero Cost] Transmitindo: {:?}", dispositivo);
dispositivo.exibir_sumario();
let bytes = dispositivo.serializar_para_wire();
println!("Payload binário transmitido: {:?} ({} bytes)", bytes, bytes.len());
}
// 5. Polimorfismo Dinâmico (Dynamic Dispatch via Trait Objects: &dyn Trait)
// Permite coleções heterogêneas contendo diferentes tipos na mesma lista!
fn despachar_lote_dinamico(dispositivos: &[&dyn DispositivoSerializavel]) {
println!("\n[DINÂMICO - Trait Object &dyn] Processando lote heterogêneo:");
for disp in dispositivos {
println!("Processando canal do dispositivo: '{}'", disp.obter_identificador());
let payload = disp.serializar_para_wire();
println!(" Bytes despachados: {:?}", payload);
}
}
fn main() {
println!("=== TRAITS, GENERICS E TRAIT BOUNDS ===");
let sensor = SensorTemperatura {
id: String::from("SENS_TEMP_ALPHA"),
temperatura_celsius: 24.85,
};
let atuador = AtuadorValvula {
id: String::from("VALV_GAS_BRAVO"),
abertura_percentual: 75,
};
// 1. Invocando função genérica estática (monomorfizada)
transmitir_estatico(&sensor);
transmitir_estatico(&atuador);
// 2. Criando coleção heterogênea com Trait Objects
let lote_hardware: Vec<&dyn DispositivoSerializavel> = vec![&sensor, &atuador];
despachar_lote_dinamico(&lote_hardware);
}
2. Saída Esperada no Terminal
=== TRAITS, GENERICS E TRAIT BOUNDS ===
[ESTÁTICO - Zero Cost] Transmitindo: SensorTemperatura { id: "SENS_TEMP_ALPHA", temperatura_celsius: 24.85 }
Dispositivo ID: 'SENS_TEMP_ALPHA' (Serialização pronta)
Payload binário transmitido: [84, 69, 77, 80, 58, 65, 198, 204, 205] (9 bytes)
[ESTÁTICO - Zero Cost] Transmitindo: AtuadorValvula { id: "VALV_GAS_BRAVO", abertura_percentual: 75 }
Dispositivo ID: 'VALV_GAS_BRAVO' (Serialização pronta)
Payload binário transmitido: [86, 65, 76, 86, 75] (5 bytes)
[DINÂMICO - Trait Object &dyn] Processando lote heterogêneo:
Processando canal do dispositivo: 'SENS_TEMP_ALPHA'
Bytes despachados: [84, 69, 77, 80, 58, 65, 198, 204, 205]
Processando canal do dispositivo: 'VALV_GAS_BRAVO'
Bytes despachados: [86, 65, 76, 86, 75]