web-dev-qa-db-fra.com

De quoi parle cet opérateur de point d'interrogation?

Je lis la documentation pour File :

//..
let mut file = File::create("foo.txt")?;
//..

Quel est le ? dans cette ligne? Je ne me souviens pas l'avoir vu dans le Rust Réservez avant.

50
Angel Angel

Comme vous l'avez peut-être remarqué, Rust ne comporte pas d'exceptions. Il panique, mais leur fonctionnalité est limitée (ils ne peuvent pas porter d'informations structurées) et leur utilisation pour la gestion des erreurs est découragée (ils sont censés pour les erreurs irrécupérables).

Dans Rust, la gestion des erreurs utilise Result . Un exemple typique serait:

fn halves_if_even(i: i32) -> Result<i32, Error> {
    if i % 2 == 0 { Ok(i/2) } else { Err(/* something */) }
}

fn do_the_thing(i: i32) -> Result<i32, Error> {
    let i = match halves_if_even(i) {
        Ok(i) => i,
        e => return e,
    };

    // use `i`
}

C'est génial parce que:

  • lors de l'écriture du code, vous ne pouvez pas oublier accidentellement de traiter l'erreur,
  • en lisant le code, vous pouvez immédiatement voir qu’il ya un risque d’erreur ici.

Ce n'est pas idéal, cependant, car il est très prolixe. C’est là que l’opérateur de point d’interrogation ? entre.

Ce qui précède peut être réécrit comme suit:

fn do_the_thing(i: i32) -> Result<i32, Error> {
    let i = halves_if_even(i)?;

    // use `i`
}

ce qui est beaucoup plus concis.

Quoi ? fait ici est équivalent à l’instruction match ci-dessus. En bref: il déballe le Result si OK et renvoie l'erreur sinon.

C'est un peu magique, mais la gestion des erreurs nécessite un peu de magie pour réduire le nombre de problèmes, et contrairement aux exceptions, il est immédiatement visible quel appel de fonction peut ou peut ne pas être une erreur: ceux qui sont ornés de ?.

Voir également:

83
Matthieu M.