El problema

Un trait que es genérico sobre su tipo de contenedor tiene requisitos de especificación de tipo: los usuarios del trait deben especificar todos sus tipos genéricos.

En el siguiente ejemplo, el trait Contiene permite el uso de los tipos genéricos A y B. Luego, el rasgo se implementa para el tipo Contenedor, especificando i32 para A y B para que pueda usarse con fn diferencia().

Debido a que Contiene es genérico, nos vemos obligados a indicar explícitamente todos los tipos genéricos para fn diferencia(). En la práctica, queremos una forma de expresar que A y B están determinados por la entrada C. Como verás en la siguiente sección, los tipos asociados proporcionan exactamente esa capacidad.

struct Contenedor(i32, i32);

// Un rasgo que verifica si hay 2 artículos almacenados dentro del contenedor.
// También recupera el primer o último valor.
trait Contiene<A, B> {
    fn contiene(&self, _: &A, _: &B) -> bool; // Requiere explícitamente `A` y `B`.
    fn primer(&self) -> i32; // No requiere explícitamente `A` o `B`.
    fn ultimo(&self) -> i32; // No requiere explícitamente `A` o `B`.
   }

impl Contiene<i32, i32> for Contenedor {
    // Verdadero si los números almacenados son iguales.
    fn contiene(&self, numero_1: &i32, numero_2: &i32) -> bool {
        (&self.0 == numero_1) && (&self.1 == numero_2)
    }

    // Coge el primer número.
    fn primer(&self) -> i32 { self.0 }

    // Coge el último número.
    fn ultimo(&self) -> i32 { self.1 }
}

// `C` contiene `A` y `B`. A la luz de eso, tener que expresar `A` y `B` nuevamente es
// una molestia.
fn diferencia<A, B, C>(contenedor: &C) -> i32 where
    C: Contiene<A, B> {
    contenedor.ultimo() - contenedor.primer()
}

fn main() {
    let numero_1 = 3;
    let numero_2 = 10;

    let contenedor = Contenedor(numero_1, numero_2);

    println!("Contenedor contienen {} y {}: {}",
        &numero_1, &numero_2,
        contenedor.contiene(&numero_1, &numero_2));
    println!("Primer número: {}", contenedor.primer());
    println!("Último número: {}", contenedor.ultimo());

    println!("la diferencia es: {}", diferencia(&contenedor));
}

See also:

structs, y traits