Menu
CoddyTech

El Enum Option revisitado

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

Ya te has encontrado con Option<T> en Rust: es la enumeración estándar para representar valores que pueden existir o no. Ahora veámoslo desde la perspectiva de la POO: Option no es solo una enumeración, sino un tipo con métodos integrados potentes que te permiten manejar valores anulables de forma segura y elegante.

En lugar de comprobar cada vez, puedes usar métodos directamente en valores de 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 si hay un valor 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 POO: el tipo Option encapsula el concepto de «quizás haya un valor» y proporciona una interfaz clara para trabajar con él. Llamas a métodos del objeto en lugar de escribir lógica externa para inspeccionarlo.

challenge icon

Desafío

Fácil

Construyamos un sistema de perfiles de usuario que gestione con elegancia los datos opcionales mediante métodos de Option. Los usuarios pueden tener un apodo o no. Tu sistema gestionará ambos casos de forma elegante y sin coincidencias explícitas.

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, como alternativa, el nombre de usuario: usa unwrap_or para gestionar esto
    • Un método formatted_nickname que devuelva un Option<String> con el apodo entre corchetes (como "[CoolNick]") si existe, o None si no hay apodo: usa map para transformar el valor
  • main.rs: Incluye el módulo del perfil y crea dos perfiles: uno con apodo y otro sin él. Muestra ambos métodos para cada perfil para ver cómo los métodos de Option gestionan de forma diferente los valores presentes y ausentes.

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

Tu salida debe seguir este formato exacto y mostrar ambos perfiles:

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

Por ejemplo, para un perfil con el nombre de usuario "alice" y el apodo "Ace", y otro con 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() {
    // Lee las 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: Crea el primer perfil con username1 y nickname1 (Some)
    
    // TODO: Crea el segundo perfil con username2 y sin apodo (None)
    
    // TODO: Imprime display_name y formatted_nickname del primer perfil
    // Usa {:?} para formatted_nickname, ya que devuelve un Option
    
    // TODO: Imprime display_name y formatted_nickname del 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 Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Rust online