Métodos en Enums
Parte de la sección Programación Orientada a Objetos del Journey de Rust de Coddy. Lección 15 de 61.
Al igual que las estructuras, los enums pueden tener métodos definidos en bloques impl. Esto te permite asociar comportamientos directamente a tu tipo enum, lo que facilita trabajar con diferentes variantes mediante una interfaz unificada.
Así es como se agrega un método al enum Message de la lección anterior:
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
impl Message {
fn describe(&self) -> String {
match self {
Message::Quit => String::from("Quit signal"),
Message::Move { x, y } => format!("Move to ({}, {})", x, y),
Message::Write(text) => format!("Message: {}", text),
}
}
}
El bloque impl Message funciona exactamente igual que con las estructuras. El método recibe &self para acceder a la instancia del enumerado. Dentro del método, usas match para determinar con qué variante estás trabajando y devolver el resultado adecuado.
Llamar al método se ve igual independientemente de qué variante tengas:
fn main() {
let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
println!("{}", m1.describe()); // Señal de salida
println!("{}", m2.describe()); // Mover a (10, 20)
}
Este patrón es potente porque quien realiza la llamada no necesita saber qué variante tiene. Simplemente llama al método, y el enumerado se encarga del resto internamente. El comportamiento cambia según la variante, pero la interfaz se mantiene coherente.
Desafío
FácilConstruirás un sistema de semáforo que utiliza una enumeración con métodos para describir el estado actual de la señal. Cada color del semáforo llevará información sobre cuánto dura, y un método proporcionará una descripción legible para las personas.
Crearás dos archivos para organizar tu código:
traffic.rs: Define una enumeración públicaTrafficLightcon tres variantes:Red: contiene unu32que representa los segundos de esperaYellow: contiene unu32que representa los segundos de esperaGreen: contiene unu32que representa los segundos para avanzar
statusque devuelva unStringdescribiendo el semáforo. Usamatchdentro del método para gestionar cada variante e incluir la duración en el mensaje.main.rs: Incorpora tu módulo de tráfico, crea instancias de cada variante del semáforo y llama al métodostatusen cada una para imprimir las descripciones.
El método status debe devolver mensajes con estos formatos exactos:
- Para
Red:Stop for {seconds} seconds - Para
Yellow:Caution for {seconds} seconds - Para
Green:Go for {seconds} seconds
Tu salida debe mostrar el estado de cada semáforo en su propia línea:
Stop for {seconds} seconds
Caution for {seconds} seconds
Go for {seconds} secondsPor ejemplo, con un semáforo en rojo de 30 segundos, amarillo de 5 segundos y verde de 25 segundos, la salida sería:
Stop for 30 seconds
Caution for 5 seconds
Go for 25 secondsRecibirás tres entradas: la duración de la luz roja, la duración de la luz amarilla y la duración de la luz verde.
Pruébalo tú mismo
mod traffic;
use traffic::TrafficLight;
fn main() {
// Leer la entrada para las duraciones
let mut red_input = String::new();
std::io::stdin().read_line(&mut red_input).expect("Failed to read line");
let red_duration: u32 = red_input.trim().parse().expect("Invalid number");
let mut yellow_input = String::new();
std::io::stdin().read_line(&mut yellow_input).expect("Failed to read line");
let yellow_duration: u32 = yellow_input.trim().parse().expect("Invalid number");
let mut green_input = String::new();
std::io::stdin().read_line(&mut green_input).expect("Failed to read line");
let green_duration: u32 = green_input.trim().parse().expect("Invalid number");
// TODO: Crea instancias de cada variante de TrafficLight con las duraciones de entrada
// TODO: Llama al método status en cada luz e imprime el resultado
}
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