Menu
Coddy logo textTech

L'opérateur point d'interrogation '?'

Fait partie de la section Logic & Flow du Journey Rust de Coddy — leçon 46 sur 66.

Lorsque vous travaillez avec des fonctions qui retournent Result, vous avez souvent besoin de gérer les erreurs soit en les traitant localement, soit en les transmettant à la fonction appelante. Rust fournit un opérateur élégant pour ce motif courant : l'opérateur point d'interrogation ?.

L'opérateur ? offre un moyen propre de propager les erreurs sans écrire d'instructions match verbeuses. Lorsque vous placez ? après un Result, il déballe automatiquement une valeur Ok ou retourne immédiatement de la fonction actuelle avec l' Err :

fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
    let number = s.parse::<i32>()?; // Si l'analyse échoue, retourne l'erreur
    Ok(number * 2) // En cas de succès, double le nombre
}

Ceci est équivalent à l'écriture d'une instruction match complète, mais beaucoup plus concis. Si s.parse::<i32>() retourne un Ok, le ? extrait la valeur et l'assigne à number. S'il retourne un Err, le ? retourne immédiatement cette erreur de l'ensemble de la fonction.

L'opérateur ? ne peut être utilisé que dans des fonctions qui retournent un Result (ou Option), car il doit être capable de retourner une erreur.

challenge icon

Défi

Facile

Vous recevrez deux entrées. La première entrée est une chaîne de caractères qui doit être analysée en un entier, et la deuxième entrée est une autre chaîne qui doit également être analysée en un entier. Créez une fonction appelée add_numbers qui prend deux tranches de chaîne (string slices) en paramètres et renvoie un Result<i32, std::num::ParseIntError>. À l'intérieur de la fonction, utilisez l'opérateur ? pour analyser les deux chaînes et renvoyer leur somme enveloppée dans Ok. Appelez la fonction avec les deux entrées et gérez le résultat en utilisant match.

Exigences :

  • Lire la première entrée (premier nombre sous forme de chaîne) et supprimer les espaces blancs
  • Lire la deuxième entrée (deuxième nombre sous forme de chaîne) et supprimer les espaces blancs
  • Créer une fonction add_numbers qui prend deux paramètres &str et renvoie Result<i32, std::num::ParseIntError>
  • À l'intérieur de la fonction, analyser la première chaîne en i32 en utilisant l'opérateur ?
  • Analyser la deuxième chaîne en i32 en utilisant l'opérateur ?
  • Renvoyer Ok(sum) où sum est l'addition des deux nombres analysés
  • Appeler la fonction avec les deux chaînes d'entrée
  • Utiliser une expression match pour gérer le Result
  • Dans la branche Ok(value), afficher : Sum: [value]
  • Dans la branche Err(_), afficher : Parsing error

Entrée :

  • Première ligne : Une chaîne représentant un nombre (par exemple, 15)
  • Deuxième ligne : Une chaîne représentant un autre nombre (par exemple, 27)

Sortie :

  • Si les deux chaînes sont des nombres valides : Sum: [result]
  • Si l'une des chaînes ne peut pas être analysée : Parsing error

Aide-mémoire

L'opérateur point d'interrogation ? fournit un moyen concis de propager les erreurs dans les fonctions qui renvoient un Result.

Lorsqu'il est placé après un Result, l'opérateur ? :

  • Déballe une valeur Ok et continue l'exécution
  • Renvoie immédiatement une Err de la fonction actuelle si une erreur survient
fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
    let number = s.parse::<i32>()?; // Si l'analyse échoue, renvoie l'erreur
    Ok(number * 2) // En cas de succès, double le nombre
}

L'opérateur ? ne peut être utilisé que dans les fonctions qui renvoient un type Result ou Option.

Essayez vous-même

use std::io;

// TODO: Créer la fonction add_numbers ici
// Elle doit prendre deux paramètres &str et retourner Result<i32, std::num::ParseIntError>


fn main() {
    // Lire la première entrée
    let mut input1 = String::new();
    io::stdin().read_line(&mut input1).expect("Failed to read line");
    let input1 = input1.trim();
    
    // Lire la deuxième entrée
    let mut input2 = String::new();
    io::stdin().read_line(&mut input2).expect("Failed to read line");
    let input2 = input2.trim();
    
    // TODO: Appeler add_numbers avec input1 et input2
    // TODO: Utiliser match pour gérer le Result
    // Afficher "Sum: [value]" pour Ok(value)
    // Afficher "Parsing error" pour Err(_)
}
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 Logic & Flow