Fácil Rust
Trait Forma com método padrão
Enunciado
Crie uma trait Forma com o método obrigatório area(&self) -> f64 e um método padrão descricao(&self) -> String que retorne "Área: X", onde X é a área formatada com {:.2}. Implemente Forma para Retangulo { largura: f64, altura: f64 } e imprima a descrição de um retângulo 3.0 x 4.0.
Requisitos
- A trait
Formatemareaobrigatória edescricaocom corpo padrão. RetanguloimplementaFormacalculandolargura * altura.maincria um retângulo 3.0 x 4.0 e imprimedescricao().
Código inicial
trait Forma {
// TODO: método area e método padrão descricao
}
struct Retangulo {
largura: f64,
altura: f64,
}
// TODO: impl Forma for Retangulo
fn main() {
// TODO: criar retângulo e imprimir descricao()
}
Saída esperada
Área: 12.00
Ver dica
No método padrão use format!("Área: {:.2}", self.area()); o {:.2} limita a duas casas decimais.
Mostrar solução
trait Forma {
fn area(&self) -> f64; // obrigatório
// método padrão: usa area(), então é herdado por quem implementa
fn descricao(&self) -> String {
format!("Área: {:.2}", self.area())
}
}
struct Retangulo {
largura: f64,
altura: f64,
}
impl Forma for Retangulo {
fn area(&self) -> f64 {
self.largura * self.altura
}
}
fn main() {
let r = Retangulo { largura: 3.0, altura: 4.0 };
println!("{}", r.descricao());
}
Passo a passo
- Declaramos
trait Formacomarea(&self) -> f64; o ponto e vírgula indica método sem corpo, ou seja obrigatório. - Dentro da trait escrevemos
descricaocom corpo: é um método padrão que já usaself.area(). - Definimos a struct
Retangulocom os camposlarguraealturado tipof64. - Em
impl Forma for Retangulofornecemos apenasarea, multiplicando os campos. - Como
descricaotem corpo padrão, não precisamos reescrevê-la —Retangulojá a ganha. - No
maincriamos o retângulo 3.0 x 4.0 e chamamosr.descricao(), que imprime a área formatada.
Por que funciona
A trait define um contrato: qualquer tipo que a implemente precisa fornecer area. O método descricao é implementado uma única vez na trait e reutilizado por todos os tipos, evitando repetição. Como descricao chama self.area(), o resultado depende da implementação específica de cada tipo, mas o código de formatação fica centralizado.
Erros comuns
- Esquecer o
&selfemarea:fn area() -> f64faz o compilador reclamar que o método não pode ser chamado comoself.area(). - Tentar implementar
descricaosemarea: o compilador acusa que o método obrigatórioareanão foi implementado. - Usar
println!("Área: {:.2}", r.area)sem parênteses: isso tenta imprimir a função, não o valor; o correto ér.area().
Outra forma de resolver
Se quiséssemos que descricao fosse diferente para cada tipo, poderíamos sobrescrevê-la no impl:
impl Forma for Retangulo {
fn area(&self) -> f64 { self.largura * self.altura }
fn descricao(&self) -> String { format!("Retângulo com área {:.2}", self.area()) }
}
Saída esperada
Área: 12.00