En este módulo, aprenderemos sobre los enums en Rust y cómo utilizar la coincidencia de patrones (pattern matching) para trabajar con ellos de manera efectiva. Los enums son una característica poderosa que permite definir un tipo que puede ser uno de varios valores diferentes. La coincidencia de patrones es una técnica que permite manejar estos valores de manera segura y expresiva.

¿Qué es un Enum?

Un enum (abreviatura de "enumeration") es un tipo que puede tener diferentes variantes. Cada variante puede tener datos asociados de diferentes tipos. Los enums son útiles cuando un valor puede ser una de varias cosas diferentes.

Definición de un Enum

Aquí hay un ejemplo básico de un enum en Rust:

enum IpAddrKind {
    V4,
    V6,
}

En este ejemplo, IpAddrKind es un enum que puede ser V4 o V6.

Usando un Enum

Para usar un enum, primero debes definir una variable de ese tipo y luego asignarle una de las variantes:

let four = IpAddrKind::V4;
let six = IpAddrKind::V6;

Enums con Datos Asociados

Los enums también pueden tener datos asociados con cada variante. Aquí hay un ejemplo más complejo:

enum IpAddr {
    V4(String),
    V6(String),
}

let home = IpAddr::V4(String::from("127.0.0.1"));
let loopback = IpAddr::V6(String::from("::1"));

En este caso, cada variante de IpAddr tiene un String asociado.

Coincidencia de Patrones

La coincidencia de patrones es una característica que permite verificar y extraer valores de enums de manera segura y concisa. La herramienta principal para la coincidencia de patrones en Rust es la expresión match.

Uso Básico de match

Aquí hay un ejemplo de cómo usar match con el enum IpAddrKind:

fn route(ip_kind: IpAddrKind) {
    match ip_kind {
        IpAddrKind::V4 => println!("Call IPv4 route"),
        IpAddrKind::V6 => println!("Call IPv6 route"),
    }
}

let four = IpAddrKind::V4;
route(four);

En este ejemplo, la función route toma un IpAddrKind y usa match para decidir qué hacer en función de la variante.

Coincidencia de Patrones con Datos Asociados

Cuando los enums tienen datos asociados, puedes extraer esos datos en la expresión match:

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

fn process_message(msg: Message) {
    match msg {
        Message::Quit => println!("Quit"),
        Message::Move { x, y } => println!("Move to ({}, {})", x, y),
        Message::Write(text) => println!("Text message: {}", text),
        Message::ChangeColor(r, g, b) => println!("Change color to RGB({}, {}, {})", r, g, b),
    }
}

let msg = Message::Move { x: 10, y: 20 };
process_message(msg);

En este ejemplo, Message es un enum con varias variantes, algunas de las cuales tienen datos asociados. La función process_message usa match para manejar cada variante y extraer los datos asociados.

Ejercicios Prácticos

Ejercicio 1: Definir y Usar un Enum

Define un enum llamado Coin que tenga variantes para Penny, Nickel, Dime y Quarter. Luego, escribe una función que tome un Coin y devuelva su valor en centavos.

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}

let coin = Coin::Dime;
println!("Value in cents: {}", value_in_cents(coin));

Ejercicio 2: Enum con Datos Asociados

Define un enum llamado Shape que tenga variantes para Circle, Rectangle y Triangle, cada una con datos asociados para sus dimensiones. Luego, escribe una función que tome un Shape y calcule su área.

enum Shape {
    Circle(f64),
    Rectangle { width: f64, height: f64 },
    Triangle { base: f64, height: f64 },
}

fn area(shape: Shape) -> f64 {
    match shape {
        Shape::Circle(radius) => std::f64::consts::PI * radius * radius,
        Shape::Rectangle { width, height } => width * height,
        Shape::Triangle { base, height } => 0.5 * base * height,
    }
}

let circle = Shape::Circle(10.0);
println!("Area of circle: {}", area(circle));

Resumen

En esta sección, hemos aprendido sobre los enums en Rust y cómo usar la coincidencia de patrones para trabajar con ellos de manera efectiva. Los enums permiten definir tipos que pueden ser uno de varios valores diferentes, y la coincidencia de patrones proporciona una forma segura y expresiva de manejar estos valores. Con estos conocimientos, estás preparado para manejar estructuras de datos más complejas y escribir código más robusto y legible en Rust.

© Copyright 2024. Todos los derechos reservados