Что такое Rust-эквивалент оператора try-catch? - PullRequest
1 голос
/ 19 апреля 2019

Возможно ли обрабатывать сразу несколько разных ошибок вместо отдельных в Rust без использования дополнительных функций ?Вкратце: что такое Rust, эквивалентный выражению try-catch?

Подобная функция ( Первоклассная обработка ошибок с ? и catch) была предложена еще в2016, но я не могу сказать, что из этого получилось и как может выглядеть решение 2019 года для такой проблемы.

Например, сделать что-то вроде этого:

try {
    do_step_1()?;
    do_step_2()?;
    do_step_3()?;
    // etc
} catch {
    alert_user("Failed to perform necessary steps");
}

Вместоиз:

match do_steps() {
    Ok(_) => (),
    _ => alert_user("Failed to perform necessary steps")
}

// Additional function:
fn do_steps() -> Result<(), Error>{
    do_step_1()?;
    do_step_2()?;
    do_step_3()?;
    // etc
    Ok(())
}

В моей программе есть функция, которая проверяет различные места в реестре на различные значения данных и возвращает некоторые совокупные данные.Необходимо будет использовать многие из этих операторов try-cache вместе с try-catch внутри других try-catch внутри циклов.

Ответы [ 2 ]

5 голосов
/ 19 апреля 2019

Result s в Rust можно связать с помощью and_then. Так что вы можете сделать это:

if let Err(e) = do_step_1().and_then(do_step_2).and_then(do_step_3) {
    println!("Failed to perform necessary steps");
}

или, если вам нужен более компактный синтаксис, вы можете сделать это с помощью макроса:

macro_rules! attempt { // `try` is a reserved keyword
   (@recurse ($a:expr) { } catch ($e:ident) $b:block) => {
      if let Err ($e) = $a $b
   };
   (@recurse ($a:expr) { $e:expr; $($tail:tt)* } $($handler:tt)*) => {
      attempt!{@recurse ($a.and_then (|_| $e)) { $($tail)* } $($handler)*}
   };
   ({ $e:expr; $($tail:tt)* } $($handler:tt)*) => {
      attempt!{@recurse ($e) { $($tail)* } $($handler)* }
   };
}

attempt!{{
   do_step1();
   do_step2();
   do_step3();
} catch (e) {
   println!("Failed to perform necessary steps: {}", e);
}}

детская площадка

5 голосов
/ 19 апреля 2019

В Rust нет оператора try catch.Наиболее близким подходом является оператор ?.

Однако вам не нужно создавать функцию и оператор match для ее разрешения в конце.Вы можете определить замыкание в своей области и использовать оператор ? внутри замыкания.Затем броски удерживаются в возвращаемом значении замыкания, и вы можете поймать его везде, где хотите:несколько разных ошибок сразу, а не по отдельности в Rust без использования дополнительных функций?

Да, это возможно.Для управления ошибками в Rust существует отказ ящик.Используя Failure, вы можете связывать, преобразовывать, объединять ошибки.После преобразования типов ошибок в один общий тип вы можете легко его отловить (обработать).

...