Rust Tipos Intermediário
derive e traits comuns
Em Rust, derive é um atributo que gera automaticamente implementações de certos traits para suas structs e enums. Isso evita escrever código repetitivo e garante que seus tipos se comportem como os tipos da biblioteca padrão. Os traits mais comuns de derivar são Debug, Clone, PartialEq, Eq e Default.
Cada trait derivado adiciona uma capacidade específica: Debug permite formatar com {:?}, Clone cria cópias explícitas, PartialEq e Eq habilitam comparações com == e !=, e Default fornece um valor padrão. O trait Display, por outro lado, não pode ser derivado, pois exige uma formatação personalizada; você deve implementá-lo manualmente.
Neste card, vamos explorar como usar derive para esses traits comuns e quando é necessário implementar Display à mão. Também veremos como o compilador impõe restrições, como a necessidade de todos os campos também implementarem o trait para que o derive funcione.
Pontos-chave
#[derive(Debug, Clone, PartialEq, Eq, Default)]gera implementações automáticas para a maioria dos traits comuns.Displaynão pode ser derivado; requer implementação manual do métodofmt.PartialEqpermite comparar com==, enquantoEqé uma marcação que indica que a igualdade é reflexiva.Defaultfornece um valor inicial;Clonepermite duplicar explicitamente com.clone().
use std::fmt;
// Deriva vários traits comuns para a struct
#[derive(Debug, Clone, PartialEq, Eq, Default)]
struct Point {
x: i32,
y: i32,
}
// Display não pode ser derivado, então implementamos manualmente
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
fn main() {
// Debug: formatação com {:?}
let p1 = Point { x: 1, y: 2 };
println!("Debug: {:?}", p1);
// Clone: cria uma cópia explícita
let p2 = p1.clone();
println!("Clone: {:?}", p2);
// PartialEq: comparação com ==
println!("PartialEq: {}", p1 == p2);
// Default: valor padrão (0, 0)
let p3 = Point::default();
println!("Default: {}", p3);
// Display: formatação personalizada
println!("Display: {}", p1);
}