← Rust EspañolChapter 10 of 13

Traits

## Objetivos de Aprendizaje - Definir e implementar traits - Usar limites de traits - Implementaciones por defecto - Dominar traits estandar comunes - Trabajar con traits genericos ## Que son los Traits? Los traits definen comportamiento compartido entre tipos: ```rust trait Summary { fn summarize(&self) -> String; } ``` ## Implementando Traits ### Implementacion Basica ```rust trait Summary { fn summarize(&self) -> String; } struct Article { title: String, author: String, } impl Summary for Article { fn summarize(&self) -> String { format!("{} by {}", self.title, self.author) } } fn main() { let article = Article { title: String::from("Rust Tutorial"), author: String::from("Alice"), }; println!("{}", article.summarize()); } ``` ### Multiples Traits ```rust trait Summarize { fn summarize(&self) -> String; } trait Printable { fn print(&self); } struct Article { title: String, author: String, } impl Summarize for Article { fn summarize(&self) -> String { format!("{} by {}", self.title, self.author) } } impl Printable for Article { fn print(&self) { println!("Title: {}\nAuthor: {}", self.title, self.author); } } ``` ## Implementaciones por Defecto ```rust trait Summary { fn summarize(&self) -> String { String::from("(Read more...)") // Implementacion por defecto } } struct Tweet { username: String, content: String, } impl Summary for Tweet { // Usa la implementacion por defecto de summarize // O sobreescribir: // fn summarize(&self) -> String { // format!("@{}: {}", self.username, self.content) // } } fn main() { let tweet = Tweet { username: String::from("alice"), content: String::from("Hello world"), }; println!("{}", tweet.summarize()); // (Read more...) } ``` ## Limites de Traits ### Sintaxis Basica ```rust fn notify(item: &impl Summary) { println!("Breaking news! {}", item.summarize()); } ``` ### Sintaxis de Limite de Trait ```rust fn notify(item: &T) { println!("Breaking news! {}", item.summarize()); } ``` ### Multiples Limites de Traits ```rust fn notify(item: &(impl Summary + Display)) { } fn notify(item: &T) { } ``` ### Clausulas where ```rust fn some_function(t: &T, u: &U) where T: Display + Clone, U: Clone + Debug, { // ... } ``` ## Implementar Metodos Condicionalmente ```rust use std::fmt::Display; struct Pair { x: T, y: T, } impl Pair { fn new(x: T, y: T) -> Self { Self { x, y } } } impl Pair { fn cmp_display(&self) { if self.x >= self.y { println!("The largest member is x = {}", self.x); } else { println!("The largest member is y = {}", self.y); } } } ``` ## Devolviendo Tipos que Implementan Traits ```rust trait Summary { fn summarize(&self) -> String; } fn returns_summarizable() -> impl Summary { Tweet { username: String::from("alice"), content: String::from("Hello"), } } ``` ## Usando Limites de Traits para Metodos Condicionales ```rust use std::fmt::Display; struct Wrapper { value: T, } impl Wrapper { fn new(value: T) -> Self { Wrapper { value } } } impl Wrapper { fn print(&self) { println!("{}", self.value); } } impl Wrapper { fn eq(&self, other: &Wrapper) -> bool { self.value == other.value } } ``` ## Traits Estandar Comunes ### Debug ```rust #[derive(Debug)] struct Rectangle { width: u32, height: u32, } fn main() { let rect = Rectangle { width: 30, height: 50 }; println!("{:?}", rect); println!("{:#?}", rect); } ``` ### Clone y Copy ```rust #[derive(Clone, Copy)] struct Point { x: i32, y: i32, } fn main() { let p1 = Point { x: 1, y: 2 }; let p2 = p1; // Copia let p3 = p1.clone(); // Clon println!("{:?}", p1); // p1 sigue siendo valido (Copy) } ``` ### PartialEq y Eq ```rust #[derive(PartialEq, Eq)] struct Point { x: i32, y: i32, } fn main() { let p1 = Point { x: 1, y: 2 }; let p2 = Point { x: 1, y: 2 }; println!("{}", p1 == p2); // true } ``` ### PartialOrd y Ord ```rust #[derive(PartialOrd, Ord)] struct Person { name: String, age: u32, } fn main() { let p1 = Person { name: "Alice".to_string(), age: 30 }; let p2 = Person { name: "Bob".to_string(), age: 25 }; println!("{}", p1 > p2); // true } ``` ### Display ```rust use std::fmt; struct Point { x: i32, y: i32, } impl fmt::Display for Point { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "({}, {})", self.x, self.y) } } fn main() { let p = Point { x: 1, y: 2 }; println!("{}", p); // (1, 2) } ``` ### Default ```rust #[derive(Default)] struct Config { width: u32, height: u32, name: String, } fn main() { let config = Config { width: 100, ..Default::default() }; } ``` ## Implementaciones Completas (Blanket Implementations) Implementar trait para todos los tipos que satisfacen los limites: ```rust use std::fmt::Display; impl T { fn print_twice(&self) { println!("{}", self); println!("{}", self); } } fn main() { 42.print_twice(); } ``` ## Supertraits Requerir que un trait implemente otro trait: ```rust use std::fmt::{Display, Debug}; trait OutlinePrint: Display { fn outline_print(&self) { let output = self.to_string(); let len = output.len(); println!("{}", "*".repeat(len + 4)); println!("* {} *", " ".repeat(len)); println!("* {} *", output); println!("* {} *", " ".repeat(len)); println!("{}", "*".repeat(len + 4)); } } struct Point { x: i32, y: i32, } impl Display for Point { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "({}, {})", self.x, self.y) } } impl OutlinePrint for Point {} ``` ## Resumen - Los traits definen comportamiento compartido (como interfaces) - Implementar traits con `impl TraitName for Type` - Las implementaciones por defecto pueden ser sobreescritas - Limites de traits: `impl Trait` o `T: Trait` - Multiples limites: `T: Trait1 + Trait2` - Clausulas where para limites complejos - `impl Trait` para tipos de retorno - Traits derive comunes: Debug, Clone, Copy, PartialEq, Eq, Default - Implementaciones completas: `impl Trait for T`

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →