Lições do módulo (2/2)
Características e limites de características
Traits definem o comportamento que um determinado tipo tem e pode compartilhar com outros tipos. Podemos usar traits para definir um conjunto de métodos que representam uma determinada funcionalidade ou interface comum, semelhante a interfaces em outras linguagens de programação.
Limites de características nos permitem especificar que um tipo genérico deve implementar uma característica específica, garantindo que os métodos necessários estejam disponíveis em tempo de compilação.
Definindo e implementando uma característica
Para definir uma característica, usamos a palavra-chave trait seguida das assinaturas dos métodos que os tipos de implementação devem definir:
pub trait Summary {
fn summarize(&self) -> String;
}Para implementar uma característica em um tipo concreto, usamos a sintaxe impl TraitName for TypeName:
pub struct NewsArticle {
pub headline: String,
pub content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}", self.headline)
}
}Limites de características
Ao escrever funções genéricas, podemos restringir os parâmetros de tipo para garantir que implementem uma característica específica. A sintaxe padrão é <T: Trait>:
pub fn notify<T: Summary>(item: &T) {
println!("Notification: {}", item.summarize());
}Alternativamente, para assinaturas mais complexas, podemos usar a cláusula where:
pub fn notify_advanced<T>(item: &T)
where
T: Summary
{
println!("Notification: {}", item.summarize());
}Experimente você mesmo
Exercício 1: A característica de resumo
Defina uma característica chamada Resumo contendo a assinatura do método fn summary(&self) -> String;. Em seguida, defina uma estrutura NewsArticle com um campo de título do tipo String e implemente o atributo Summary para ele, para que o método summary retorne o valor do campo de título.
Mostrar dica
Defina a característica `Summary` e a estrutura`NewsArticle`. Implemente com `impl Summary for NewsArticle`clonando o campo`self.headline.clone()`.
Solução disponível após 3 tentativas
Exercício 2: Limites de características com print_summary
Com base no código do exercício anterior, defina uma função genérica chamada print_summary<T> que aceite um item de parâmetro do tipo &T. Aplique um limite de característica para que T deva implementar a característica Resumo. Dentro da função, imprima o resultado retornado por item.summarize().
Mostrar dica
Use a assinatura `fn print_summary<T: Summary>(item: &T)`e invoque`item.summarize()`dentro de `println!`.
Solução disponível após 3 tentativas
Exercício 3: Cálculo de área usando características
Defina uma característica chamada Área com o método fn area(&self) -> f64;. Crie uma estrutura Circle contendo um campo de raio do tipo f64 e implemente a característica Área para ele calculando a área (fórmula: raio * raio * 3,14159).
Mostrar dica
Defina a característica `Area` e a estrutura`Circle`. Implemente `area(&self)` usando a fórmula da área do círculo.
Solução disponível após 3 tentativas