Implementación de Traits
Parte de la sección Programación Orientada a Objetos del Journey de Rust de Coddy. Lección 30 de 61.
Ahora que sabes cómo definir un trait, veamos cómo hacer que una estructura cumpla ese contrato. Implementar un trait conecta el requisito abstracto con un comportamiento concreto.
La sintaxis usa impl TraitName for StructName:
trait Speak {
fn speak(&self) -> String;
}
struct Dog {
name: String,
}
impl Speak for Dog {
fn speak(&self) -> String {
format!("{} says: Woof!", self.name)
}
}
El bloque impl Speak for Dog le indica a Rust que Dog está implementando el trait Speak. Dentro, proporcionas el cuerpo real del método. Aquí es donde defines cómo habla un perro.
El poder de los traits queda claro cuando varios tipos implementan el mismo:
struct Cat {
name: String,
}
impl Speak for Cat {
fn speak(&self) -> String {
format!("{} says: Meow!", self.name)
}
}
Tanto Dog como Cat ahora comparten la capacidad Speak, pero cada uno proporciona su propia implementación única. Puedes llamar a .speak() en cualquiera de los dos tipos:
let dog = Dog { name: String::from("Rex") };
let cat = Cat { name: String::from("Whiskers") };
println!("{}", dog.speak()); // Rex dice: ¡Guau!
println!("{}", cat.speak()); // Whiskers dice: ¡Miau!
Esta es la base del polimorfismo en Rust: distintos tipos, la misma interfaz, comportamientos únicos.
Desafío
Fácil¡Demos vida a los rasgos implementándolos para distintos tipos! Crearás un rasgo Describable y lo implementarás para dos estructuras diferentes, cada una proporcionando su propia descripción única.
Organizarás tu código en tres archivos:
describable.rs: Define un rasgo públicoDescribablecon un métododescribe(&self) -> String.items.rs: Crea dos estructuras públicas que implementen tu rasgo:Bookcon un campo públicotitle(String)Moviecon un campo públiconame(String)
Describablecon su propio formato de descripción único.main.rs: Reúne tus módulos, crea instancias de ambas estructuras y llama a sus métodosdescribepara mostrar cómo el mismo rasgo produce salidas diferentes para distintos tipos.
Tu Book debe describirse como Book: {title} y tu Movie debe describirse como Film: {name}. ¡Observa cómo cada tipo cumple el mismo contrato, pero con su propio comportamiento!
En tu archivo principal, crea un libro y una película usando las dos entradas proporcionadas y, después, imprime sus descripciones en líneas separadas.
Tu salida debe seguir este formato:
Book: {title}
Film: {name}Por ejemplo, con las entradas 1984 e Inception:
Book: 1984
Film: InceptionRecibirás dos entradas: el título de un libro y el nombre de una película.
Pruébalo tú mismo
mod describable;
mod items;
use describable::Describable;
use items::{Book, Movie};
fn main() {
// Lee las entradas
let mut title = String::new();
std::io::stdin().read_line(&mut title).expect("Failed to read line");
let title = title.trim().to_string();
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
// TODO: Crea una instancia de Book con el title
// TODO: Crea una instancia de Movie con el name
// TODO: Imprime la descripción del libro
// TODO: Imprime la descripción de la película
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Métodos y Comportamiento
Intro a Bloques de ImplementaciónEl Parámetro SelfMétodos MutablesFunciones AsociadasMúltiples Bloques de ImplementaciónEncadenamiento de MétodosResumen - Acciones de Rectángulo4Proyecto: Mascota virtual
Definir la mascotaAlimentar a la mascota7Traits estándar
El trait DebugEl trait DisplayClone y CopyTraits de igualdadResumen - Punto imprimible10Proyecto: Sistema de documentos
El Trait DrawComponente de texto2Encapsulamiento y módulos
Conceptos básicos de módulosLa palabra clave PublicCampos privadosGettersSettersRepaso - Casillero seguro5Genéricos
Estructuras genéricasMétodos genéricosMúltiples tipos genéricosFunciones genéricasResumen - Punto de coordenadas8Traits como límites
Sintaxis de límites de traitsLímites múltiplesLa cláusula whereRetornar tipos con traitsResumen: Impresora genérica11Patrones de diseño en Rust
Patrón NewtypeComposiciónEl Trait DropFrom e IntoResumen - Mock de Smart Pointer3Enums avanzados
Enums con datosMétodos en EnumsCoincidencia de variantes de datosEl Enum Option revisitadoResumen - Enum Shape6Definición de Traits
¿Qué es un Trait?Implementación de TraitsImplementaciones por defectoSobrescribir valores por defectoTraits con parámetrosResumen - Reproductor multimediaPractica por tu cuenta: Compilador de Rust online