Menu
Coddy logo textTech

Enums con datos

Parte de la sección Programación Orientada a Objetos del Journey de Rust de Coddy. Lección 14 de 61.

Los enums básicos en Rust te permiten definir un tipo con un conjunto fijo de variantes, como Direction::North o Status::Active. Pero los enums de Rust son mucho más potentes que eso. Cada variante puede contener sus propios datos, lo que hace que los enums sean increíblemente flexibles para modelar situaciones del mundo real.

Considera un sistema de mensajería en el que distintos tipos de mensajes contienen información diferente. Un mensaje de texto tiene contenido, un comando de movimiento tiene coordenadas y una señal de salida no tiene nada en absoluto. En Rust, puedes representar todos estos casos con un solo enum:

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(u8, u8, u8),
}

Cada variante tiene una forma diferente. Quit no contiene datos: es solo una señal.

Move utiliza una sintaxis similar a la de las estructuras, con campos con nombre. Write contiene un único String mediante una sintaxis de tupla. ChangeColor contiene tres valores que representan componentes RGB.

Crear instancias de estas variantes se ve así:

let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
let m3 = Message::Write(String::from("Hello"));
let m4 = Message::ChangeColor(255, 128, 0);

La belleza de este enfoque es que m1, m2, m3 y m4 son todos del mismo tipo: Message. Puedes almacenarlos en la misma colección, pasarlos a la misma función o devolver cualquier variante desde una sola función. El enum unifica diferentes estructuras de datos bajo un mismo tipo, al tiempo que conserva la información específica que necesita cada variante.

challenge icon

Desafío

Fácil

Construyamos un sistema de notificaciones que use enumeraciones con datos para representar distintos tipos de alertas. Cada tipo de notificación contiene información diferente: algunas tienen mensajes, otras tienen valores numéricos y otras son señales simples.

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

  • notification.rs: Define una enumeración pública Notification con tres variantes:
    • Alert: contiene un único mensaje String (sintaxis de tupla)
    • Reminder: contiene campos con nombre: title (String) y minutes (u32)
    • Dismiss: no contiene datos, solo es una señal
  • main.rs: Incorpora tu módulo de notificaciones y crea una instancia de cada variante. Después, imprime información sobre cada notificación para demostrar que las tres variantes son del mismo tipo, pero contienen datos diferentes.

Al imprimir, usa el formato de depuración ({:?}) para mostrar cada notificación. Tendrás que derivar el trait Debug en tu enumeración para poder imprimirla de esta manera.

Tu salida debe mostrar las tres notificaciones, cada una en su propia línea:

Alert("{message}")
Reminder { title: "{title}", minutes: {minutes} }
Dismiss

Por ejemplo, con un mensaje de alerta "Server down", un recordatorio con el título "Meeting" y 30 minutos, la salida sería:

Alert("Server down")
Reminder { title: "Meeting", minutes: 30 }
Dismiss

Recibirás tres entradas: el mensaje de alerta, el título del recordatorio y los minutos del recordatorio.

Pruébalo tú mismo

mod notification;

use notification::Notification;

fn main() {
    // Leer entradas
    let mut alert_message = String::new();
    std::io::stdin().read_line(&mut alert_message).expect("Failed to read line");
    let alert_message = alert_message.trim().to_string();

    let mut reminder_title = String::new();
    std::io::stdin().read_line(&mut reminder_title).expect("Failed to read line");
    let reminder_title = reminder_title.trim().to_string();

    let mut minutes_input = String::new();
    std::io::stdin().read_line(&mut minutes_input).expect("Failed to read line");
    let reminder_minutes: u32 = minutes_input.trim().parse().expect("Failed to parse minutes");

    // TODO: Crea una notificación Alert usando el alert_message

    // TODO: Create a Reminder notification using reminder_title and reminder_minutes

    // TODO: Crea una notificación Dismiss

    // TODO: Imprime cada notificación usando el formato de depuración {:?}
    // Cada notificación debe imprimirse en su propia línea
}
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 Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Rust online