Gestion des erreurs en Rust avec le point d'interrogation

Beginner

This tutorial is from open-source community. Access the source code

Introduction

Dans ce laboratoire, nous allons apprendre à utiliser l'opérateur ? en Rust, qui nous permet de simplifier la gestion des erreurs en renvoyant Err au lieu de générer une panique. Nous explorerons également le macro try!, qui avait une fonctionnalité similaire avant l'introduction de ?.

Note : Si le nom de fichier n'est pas spécifié dans le laboratoire, vous pouvez utiliser n'importe quel nom de fichier. Par exemple, vous pouvez utiliser main.rs, le compiler et l'exécuter avec rustc main.rs &&./main.

Présentation de ?

Parfois, nous voulons simplement la simplicité de unwrap sans le risque d'avoir une panic. Jusqu'à présent, unwrap nous a contraint à imbriquer les appels de plus en plus profondément alors que ce que nous voulions vraiment était d'obtenir la variable en dehors. C'est exactement le but de ?.

Lorsque l'on trouve une Err, il y a deux actions valides à prendre :

  1. panic! que nous avons déjà décidé d'éviter le plus possible
  2. return car une Err signifie qu'elle ne peut pas être traitée

? est _presque_[^†] exactement équivalent à un unwrap qui return au lieu de panicuer en cas d'Err. Voyons comment nous pouvons simplifier l'exemple précédent qui utilisait des combinateurs :

use std::num::ParseIntError;

fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    let first_number = first_number_str.parse::<i32>()?;
    let second_number = second_number_str.parse::<i32>()?;

    Ok(first_number * second_number)
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n est {}", n),
        Err(e) => println!("Erreur : {}", e),
    }
}

fn main() {
    print(multiply("10", "2"));
    print(multiply("t", "2"));
}

Le macro try!

Avant l'arrivée de ?, la même fonctionnalité était obtenue avec la macro try!. L'opérateur ? est maintenant recommandé, mais vous pouvez encore trouver try! dans du code plus ancien. La même fonction multiply de l'exemple précédent ressemblerait à ceci en utilisant try! :

// Pour compiler et exécuter cet exemple sans erreurs, en utilisant Cargo, changez
// la valeur du champ `edition`, dans la section `[package]` du fichier `Cargo.toml`, en "2015".

use std::num::ParseIntError;

fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    let first_number = try!(first_number_str.parse::<i32>());
    let second_number = try!(second_number_str.parse::<i32>());

    Ok(first_number * second_number)
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n est {}", n),
        Err(e) => println!("Erreur : {}", e),
    }
}

fn main() {
    print(multiply("10", "2"));
    print(multiply("t", "2"));
}

Sommaire

Félicitations ! Vous avez terminé le laboratoire Présentation de ?. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.