Menu
Coddy logo textTech

L'Enum Option revisitée

Fait partie de la section Programmation Orientée Objet du Journey Rust de Coddy. Leçon 17 sur 61.

Vous avez déjà rencontré Option<T> en Rust : c’est l’énumération standard permettant de représenter des valeurs qui peuvent exister ou non. Examinons-la maintenant sous l’angle de la POO : Option n’est pas seulement une énumération, c’est un type doté de méthodes intégrées puissantes qui vous permettent de gérer les valeurs nullables de manière sûre et élégante.

Au lieu d’effectuer une correspondance à chaque fois, vous pouvez utiliser directement des méthodes sur les valeurs Option. La méthode unwrap_or renvoie la valeur interne si elle existe, ou une valeur par défaut que vous fournissez :

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

La méthode map transforme la valeur interne si elle existe, en laissant None inchangé. Cela vous permet d’enchaîner les opérations sans devoir vérifier constamment la présence de 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

Ces méthodes incarnent les principes de la POO : le type Option encapsule le concept de « peut-être une valeur » et fournit une interface claire pour travailler avec celui-ci. Vous appelez des méthodes sur l’objet plutôt que d’écrire une logique externe pour l’inspecter.

challenge icon

Défi

Facile

Construisons un système de profils utilisateur qui gère élégamment les données facultatives à l’aide des méthodes de Option. Les utilisateurs peuvent avoir un pseudonyme défini, ou ne pas en avoir. Votre système gérera les deux cas avec élégance, sans correspondance explicite.

Vous allez créer deux fichiers pour organiser votre code :

  • profile.rs : définissez une structure publique Profile avec deux champs : username (String) et nickname (Option<String>). Implémentez :
    • Un constructeur new qui prend un nom d’utilisateur et un pseudonyme facultatif
    • Une méthode display_name qui renvoie le pseudonyme s’il existe, ou le nom d’utilisateur comme solution de repli : utilisez unwrap_or pour gérer cela
    • Une méthode formatted_nickname qui renvoie un Option<String> contenant le pseudonyme entre crochets (comme "[CoolNick]") s’il existe, ou None s’il n’y a pas de pseudonyme : utilisez map pour transformer la valeur
  • main.rs : importez votre module de profil et créez deux profils : un avec un pseudonyme et un sans pseudonyme. Démontrez les deux méthodes sur chaque profil afin de montrer comment les méthodes de Option gèrent différemment les valeurs présentes et absentes.

Pour la méthode formatted_nickname, utilisez le formatage de débogage ({:?}) lors de l’affichage, puisqu’elle renvoie un Option.

Votre sortie doit respecter exactement le format suivant, en affichant les deux profils :

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

Par exemple, avec un profil pour le nom d’utilisateur "alice" et le pseudonyme "Ace", et un autre pour le nom d’utilisateur "bob" sans pseudonyme, la sortie serait :

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

Vous recevrez trois entrées : le premier nom d’utilisateur, le pseudonyme du premier utilisateur et le deuxième nom d’utilisateur (qui n’a pas de pseudonyme).

Essayez vous-même

mod profile;

use profile::Profile;

fn main() {
    // Lire les entrées
    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: Créer le premier profil avec username1 et nickname1 (Some)
    
    // TODO: Create second profile with username2 and no nickname (None)
    
    // TODO: Print display_name and formatted_nickname for first profile
    // Use {:?} for formatted_nickname since it returns an Option
    
    // TODO: Print display_name and formatted_nickname for second profile
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur Rust en ligne