Menu
Coddy logo textTech

Coincidencia de variantes de datos

Parte de la sección Object Oriented Programming del Journey de Rust de Coddy — lección 16 de 61.

En la lección anterior, utilizaste match dentro de los métodos de enum para manejar diferentes variantes. Ahora enfoquémonos en cómo match extrae realmente los datos almacenados dentro de esas variantes, una técnica llamada desestructuración.

Cuando haces coincidir una variante de un 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 brazo extrae datos de manera diferente según la estructura de la variante. Para las variantes de tipo estructura, se utiliza { field_name } para extraer campos con nombre. Para las variantes de tupla, se utilizan variables posicionales como (width, height).

Los nombres de las variables que elijas pasan a estar disponibles dentro de esa rama del match. Esto es potente porque estás comprobando simultáneamente qué variante tienes y obteniendo acceso a su contenido.

El compilador garantiza que manejes cada variante, y los valores extraídos están listos para usarse de inmediato; no se necesitan pasos adicionales.

challenge icon

Desafío

Fácil

Vamos a construir un procesador de comandos que maneje diferentes tipos de comandos de usuario. Cada comando lleva datos diferentes, y tu procesador utilizará la coincidencia de patrones (pattern matching) para extraer esos datos y producir las respuestas adecuadas.

Crearás dos archivos para organizar tu código:

  • command.rs: Define un enum público Command con tres variantes:
    • Say — contiene un único mensaje String (sintaxis de tupla)
    • Move — contiene campos con nombre: direction (String) y steps (u32)
    • Calculate — contiene dos valores i32 que representan los números a sumar (sintaxis de tupla)
    Luego, implementa un método execute que utilice match para desestructurar cada variante y devolver un String que describa la acción realizada.
  • main.rs: Importa tu módulo de comandos, crea una instancia de cada variante de comando utilizando las entradas proporcionadas y llama al método execute en cada una para imprimir los resultados.

Tu método execute debe desestructurar cada variante para acceder a sus datos y devolver mensajes en 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 de "Hello world", un movimiento de 5 pasos al "north", y un cálculo de 10 y 25, la salida sería:

Saying: Hello world
Moving 5 steps north
10 + 25 = 35

Recibirás cinco entradas: el mensaje de say, la dirección, el número de pasos y los dos números para calcular.

Hoja de referencia

La coincidencia de patrones con match te permite desestructurar variantes de enum y extraer sus datos directamente en el patrón.

Para variantes de tupla, usa variables posicionales:

enum Event {
    KeyPress(char),
    Resize(u32, u32),
}

match event {
    Event::KeyPress(key) => {
        println!("Key: {}", key);
    }
    Event::Resize(width, height) => {
        println!("{}x{}", width, height);
    }
}

Para variantes tipo estructura, usa la sintaxis de campos con nombre:

enum Event {
    Click { x: i32, y: i32 },
}

match event {
    Event::Click { x, y } => {
        println!("Clicked at ({}, {})", x, y);
    }
}

Las variables extraídas pasan a estar disponibles dentro de su respectivo brazo de match, lo que te permite comprobar el tipo de variante y acceder a sus datos simultáneamente.

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: Crear un comando Say usando say_message y ejecutarlo
    
    // TODO: Crear un comando Move usando direction y steps, y ejecutarlo
    
    // TODO: Crear un comando Calculate usando num1 y num2, y ejecutarlo
    
    // TODO: Imprimir los resultados de la ejecución de cada comando
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Object Oriented Programming