Capítulo 13: Generics (Tipos Genéricos) ⌚👽
Neste capítulo, vamos aprender a criar funções e estruturas que funcionam com qualquer tipo de dado usando os Generics no Rust, com o tema Ben 10!
📖 O que são Generics?
Assim como os Templates no C++, os Generics (Genéricos) no Rust permitem que escrevamos código que funciona com múltiplos tipos de dados, sem precisar repetir o código para cada tipo. O Omnitrix é o exemplo perfeito: um único relógio que assume qualquer forma alienígena!
📖 Exemplo Guiado: O Omnitrix Genérico
Vamos criar uma função genérica que exibe o nível de poder de um alien. O poder pode ser um número inteiro ou um texto!
- Crie o arquivo
omnitrix_generics.rsna pastasrc/:
// O <T> indica que a função aceita um tipo genérico T
// Usamos std::fmt::Display para garantir que o tipo T possa ser impresso!
fn exibir_poder<T: std::fmt::Display>(nome_alien: &str, poder: T) {
println!("Alien: {} | Poder: {}", nome_alien, poder);
}
fn main() {
println!("--- Omnitrix Ativado ---");
// Usando com Inteiro
exibir_poder("Quatro Bracos", 100);
// Usando com String Slice (&str)
exibir_poder("XLR8", "Velocidade da Luz");
// Usando com Float
exibir_poder("Chama", 95.5);
}🕹️ Como Executar e Testar no VS Code
- Abra o terminal integrado.
- Compile:
rustc omnitrix_generics.rs - Execute:
./omnitrix_generics
Resultado Esperado:
--- Omnitrix Ativado ---
Alien: Quatro Bracos | Poder: 100
Alien: XLR8 | Poder: Velocidade da Luz
Alien: Chama | Poder: 95.5📊 Ilustração Visual: Funcionamento do Generic
O compilador gera a versão correta da função na hora de compilar:
graph TD A["Template: exibir_poder<T>"] -->|"Se usar int"| B["Função gerada para i32"] A -->|"Se usar &str"| C["Função gerada para &str"]
🛠️ Prática Obrigatória 1: Caixa de Item Misterioso
Crie uma struct genérica chamada Bau<T> que guarde um único item de qualquer tipo no campo conteudo. Crie um bloco impl genérico para ela com um método abrir(&self) que exiba o conteúdo do baú!
🔑 Gabarito de Código
Prática 1: bau_generico.rs
struct Bau<T> {
conteudo: T,
}
impl<T: std::fmt::Display> Bau<T> {
fn abrir(&self) {
println!("Voce abriu o bau e encontrou: {}", self.conteudo);
}
}
fn main() {
let bau_ouro = Bau { conteudo: 1000 }; // Bau com ouro (inteiro)
let bau_espada = Bau { conteudo: String::from("Espada Mestra") }; // Bau com texto
bau_ouro.abrir();
bau_espada.abrir();
}