Métodos Padrão

Traits podem implementar o comportamento em termos de outros métodos de trait:

trait Equals {
    fn equals(&self, other: &Self) -> bool;
    fn not_equals(&self, other: &Self) -> bool {
        !self.equals(other)
    }
}

#[derive(Debug)]
struct Centimeter(i16);

impl Equals for Centimeter {
    fn equals(&self, other: &Centimeter) -> bool {
        self.0 == other.0
    }
}

fn main() {
    let a = Centimeter(10);
    let b = Centimeter(20);
    println!("{a:?} igual a {b:?}: {}", a.equals(&b));
    println!("{a:?} diferente de {b:?}: {}", a.not_equals(&b));
}
  • Traits podem especificar métodos pré-implementados (padrão) e métodos que os usuários são obrigados a implementar. Os métodos com implementações padrão podem contar com os métodos requeridos.

  • Mova o método not_equals para um novo trait NotEquals.

  • Faça Equals um super trait para NotEquals.

    trait NotEquals: Equals {
        fn not_equals(&self, other: &Self) -> bool {
            !self.equals(other)
        }
    }
  • Forneça uma implementação geral de NotEquals para Equals.

    trait NotEquals {
        fn not_equals(&self, other: &Self) -> bool;
    }
    
    impl<T> NotEquals for T where T: Equals {
        fn not_equals(&self, other: &Self) -> bool {
            !self.equals(other)
        }
    }
    • Com a implementação geral, você não precisa mais de Equals como um super trait para NotEqual.