Lecciones del módulo (2/2)
Traits y Trait Bounds
Los traits definen el comportamiento que un tipo particular posee y puede compartir con otros tipos. Podemos usar los traits para definir un conjunto de métodos que representan una determinada funcionalidad o interfaz común, de manera similar a las interfaces en otros lenguajes de programación.
Los trait bounds (restricciones de trait) permiten especificar que un tipo genérico debe implementar un determinado trait, garantizando que los métodos requeridos estén disponibles en tiempo de compilación.
Definir e Implementar un Trait
Para definir un trait, usamos la palabra clave trait seguida de las firmas de los métodos que los tipos deberán implementar:
pub trait Summary {
fn summarize(&self) -> String;
}
Para implementar un trait en un tipo concreto, usamos la sintaxis impl TraitName for TypeName:
pub struct NewsArticle {
pub headline: String,
pub content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}", self.headline)
}
}
Trait Bounds (Restricciones de Trait)
Cuando escribimos funciones genéricas, podemos restringir los parámetros de tipo para asegurarnos de que implementen un trait específico. La sintaxis estándar es <T: Trait>:
pub fn notify<T: Summary>(item: &T) {
println!("Notifica: {}", item.summarize());
}
Como alternativa, para firmas más complejas, podemos usar la cláusula where:
pub fn notify_advanced<T>(item: &T)
where
T: Summary
{
println!("Notifica: {}", item.summarize());
}
Pruébalo tú
Ejercicio 1: El Trait Summary
Define un trait llamado Summary que contenga la firma del método fn summarize(&self) -> String;. Luego define una struct NewsArticle con un campo headline de tipo String e implementa el trait Summary para ella de manera que el método summarize devuelva el valor del campo headline.
Mostrar pista
Define el trait `Summary`y la struct`NewsArticle`. Implementa con `impl Summary for NewsArticle`clonando el campo`self.headline.clone()`.
Solución disponible después de 3 intentos
Ejercicio 2: Trait Bounds con print_summary
Basándote en el código del ejercicio anterior, define una función genérica llamada print_summary<T> que acepte un parámetro item de tipo &T. Aplica una restricción (trait bound) para que T deba implementar el trait Summary. Dentro de la función, imprime en pantalla el resultado devuelto por item.summarize().
Mostrar pista
Usa la firma `fn print_summary<T: Summary>(item: &T)`e invoca`item.summarize()`dentro del`println!`.
Solución disponible después de 3 intentos
Ejercicio 3: Calculo del Área mediante Trait
Define un trait llamado Area con el método fn area(&self) -> f64;. Crea una struct Circle que contenga un campo radius de tipo f64, e implementa el trait Area para ella calculando el área (fórmula: radius * radius * 3.14159).
Mostrar pista
Define el trait `Area`y la struct`Circle`. Implementa `area(&self)` usando la fórmula del círculo.
Solución disponible después de 3 intentos