Coincidencia de variantes de datos
Parte de la sección Programación Orientada a Objetos del Journey de Rust de Coddy. Lección 16 de 61.
En la lección anterior, usaste match dentro de los métodos de enum para manejar diferentes variantes. Ahora centrémonos en cómo match extrae realmente los datos almacenados dentro de esas variantes: una técnica llamada desestructuración.
Cuando haces match con una variante de enum que contiene datos, puedes vincular esos datos a variables directamente en el patrón:
enum Event {
Click { x: i32, y: i32 },
KeyPress(char),
Resize(u32, u32),
}
fn handle_event(event: Event) {
match event {
Event::Click { x, y } => {
println!("Clicked at ({}, {})", x, y);
}
Event::KeyPress(key) => {
println!("Key pressed: {}", key);
}
Event::Resize(width, height) => {
println!("Resized to {}x{}", width, height);
}
}
}
Cada rama extrae los datos de forma diferente según la estructura de la variante. Para las variantes similares a estructuras, usas { field_name } para extraer campos con nombre. Para las variantes de tupla, usas variables posicionales como (width, height).
Los nombres de variables que eliges pasan a estar disponibles dentro de esa rama de match. Esto es potente porque, al mismo tiempo, compruebas qué variante tienes y obtienes acceso a su carga útil.
El compilador garantiza que manejes cada variante, y los valores extraídos están listos para usarse de inmediato: no se necesitan pasos adicionales.
Desafío
FácilConstruirás un procesador de comandos que maneje distintos tipos de comandos de usuario. Cada comando contiene datos diferentes, y tu procesador usará la coincidencia de patrones para extraer esos datos y producir respuestas adecuadas.
Crearás dos archivos para organizar tu código:
command.rs: Define un enum públicoCommandcon tres variantes:Say: contiene un único mensajeString(sintaxis de tupla)Move: contiene campos con nombre:direction(String) ysteps(u32)Calculate: contiene dos valoresi32que representan los números que se sumarán (sintaxis de tupla)
executeque usematchpara desestructurar cada variante y devolver unStringque describa la acción realizada.main.rs: Incluye tu módulo de comandos, crea una instancia de cada variante de comando usando las entradas proporcionadas y llama al métodoexecuteen cada una para imprimir los resultados.
Tu método execute debe desestructurar cada variante para acceder a sus datos y devolver mensajes con estos formatos exactos:
- Para
Say:Saying: {message} - Para
Move:Moving {steps} steps {direction} - Para
Calculate:{a} + {b} = {sum}
Tu salida debe mostrar el resultado de cada comando en su propia línea:
Saying: {message}
Moving {steps} steps {direction}
{a} + {b} = {sum}Por ejemplo, con un mensaje de say "Hello world", un movimiento de 5 pasos hacia "north" y un cálculo de 10 y 25, la salida sería:
Saying: Hello world
Moving 5 steps north
10 + 25 = 35Recibirás cinco entradas: el mensaje de say, la dirección, el número de pasos y los dos números que se calcularán.
Pruébalo tú mismo
mod command;
use command::Command;
fn main() {
// Leer entradas
let mut say_message = String::new();
std::io::stdin().read_line(&mut say_message).expect("Failed to read line");
let say_message = say_message.trim().to_string();
let mut direction = String::new();
std::io::stdin().read_line(&mut direction).expect("Failed to read line");
let direction = direction.trim().to_string();
let mut steps_input = String::new();
std::io::stdin().read_line(&mut steps_input).expect("Failed to read line");
let steps: u32 = steps_input.trim().parse().expect("Failed to parse steps");
let mut num1_input = String::new();
std::io::stdin().read_line(&mut num1_input).expect("Failed to read line");
let num1: i32 = num1_input.trim().parse().expect("Failed to parse num1");
let mut num2_input = String::new();
std::io::stdin().read_line(&mut num2_input).expect("Failed to read line");
let num2: i32 = num2_input.trim().parse().expect("Failed to parse num2");
// TODO: Crea un comando Say usando say_message y ejecútalo
// TODO: Crea un comando Move usando direction y steps, y ejecútalo
// TODO: Crea un comando Calculate usando num1 y num2, y ejecútalo
// TODO: Imprime los resultados de cada ejecución de comando
}
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