Menu
Coddy logo textTech

El Enum Option revisitado

Parte de la sección Object Oriented Programming del Journey de Rust de Coddy. Lección 17 de 61.

Ya te has encontrado con Option<T> en Rust; es el enum estándar para representar valores que pueden existir o no. Ahora veámoslo a través de una lente de OOP: Option no es solo un enum, es un tipo con potentes métodos integrados que te permiten manejar valores nulos de forma segura y elegante.

En lugar de usar coincidencia de patrones cada vez, puedes usar métodos directamente en valores Option. El método unwrap_or devuelve el valor interno si existe, o un valor predeterminado que proporciones:

let maybe_name: Option<String> = Some(String::from("Alice"));
let name = maybe_name.unwrap_or(String::from("Guest"));
println!("{}", name);  // Alice

let empty: Option<String> = None;
let fallback = empty.unwrap_or(String::from("Guest"));
println!("{}", fallback);  // Guest

El método map transforma el valor interno si existe, dejando None sin cambios. Esto te permite encadenar operaciones sin tener que comprobar constantemente None:

let maybe_num: Option<i32> = Some(5);
let doubled = maybe_num.map(|x| x * 2);
println!("{:?}", doubled);  // Some(10)

let nothing: Option<i32> = None;
let still_nothing = nothing.map(|x| x * 2);
println!("{:?}", still_nothing);  // None

Estos métodos encarnan los principios de la OOP: el tipo Option encapsula el concepto de "tal vez un valor" y proporciona una interfaz limpia para trabajar con él. Se llaman a los métodos en el objeto en lugar de escribir lógica externa para inspeccionarlo.

challenge icon

Desafío

Fácil

Vamos a construir un sistema de perfil de usuario que maneje con elegancia los datos opcionales utilizando métodos de Option. Los usuarios pueden tener un apodo establecido o no; tu sistema manejará ambos casos de forma elegante sin necesidad de un emparejamiento explícito.

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

  • profile.rs: Define una estructura pública Profile con dos campos: username (String) y nickname (Option<String>). Implementa:
    • Un constructor new que reciba un nombre de usuario y un apodo opcional
    • Un método display_name que devuelva el apodo si existe, o el nombre de usuario como alternativa; utiliza unwrap_or para manejar esto
    • Un método formatted_nickname que devuelva un Option<String> con el apodo envuelto entre corchetes (como "[CoolNick]") si existe, o None si no hay apodo; utiliza map para transformar el valor
  • main.rs: Incorpora tu módulo de perfil y crea dos perfiles: uno con apodo y otro sin él. Demuestra ambos métodos en cada perfil para mostrar cómo los métodos de Option manejan los valores presentes y ausentes de manera diferente.

Para el método formatted_nickname, utiliza el formato de depuración ({:?}) al imprimir, ya que devuelve un Option.

Tu salida debe seguir este formato exacto, mostrando ambos perfiles:

Display name: {name}
Formatted nickname: {option}
Display name: {name}
Formatted nickname: {option}

Por ejemplo, con un perfil para el nombre de usuario "alice" con el apodo "Ace", y otro para el nombre de usuario "bob" sin apodo, la salida sería:

Display name: Ace
Formatted nickname: Some("[Ace]")
Display name: bob
Formatted nickname: None

Recibirás tres entradas: el primer nombre de usuario, el apodo del primer usuario y el segundo nombre de usuario (que no tiene apodo).

Pruébalo tú mismo

mod profile;

use profile::Profile;

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

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

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

    // TODO: Crear el primer perfil con username1 y nickname1 (Some)
    
    // TODO: Crear el segundo perfil con username2 y sin apodo (None)
    
    // TODO: Imprimir display_name y formatted_nickname para el primer perfil
    // Usa {:?} para formatted_nickname ya que devuelve un Option
    
    // TODO: Imprimir display_name y formatted_nickname para el segundo perfil
}
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

Practica por tu cuenta: Compilador de Rust online