Trait Bounds

Cuando se trabaja con genéricos, a menudo se prefiere que los tipos implementen algún trait, de forma que se pueda llamar a los métodos de este trait.

Puedes hacerlo con T: Trait o impl Trait:

fn duplicate<T: Clone>(a: T) -> (T, T) {
    (a.clone(), a.clone())
}

// struct NotClonable;

fn main() {
    let foo = String::from("foo");
    let pair = duplicate(foo);
    println!("{pair:?}");
}
This slide should take about 8 minutes.
  • Prueba a crear un NonClonable y pásalo a duplicable.

  • Si se necesitan varios traits, usa + para unirlos.

  • Muestra una cláusula where para que los alumnos la encuentren al leer el código.

    fn duplicate<T>(a: T) -> (T, T)
    where
        T: Clone,
    {
        (a.clone(), a.clone())
    }
    • Despeja la firma de la función si tienes muchos parámetros.
    • Tiene funciones adicionales para que sea más potente.
      • Si alguien pregunta, la función adicional es que el tipo que está a la izquierda de ":" puede ser arbitrario, como Option<T>.
  • Ten en cuenta que Rust (todavía) no admite especialización. Por ejemplo, dado el duplicate, original, no es válido añadir un duplicate(a: u32) especializado.