Error handling trust与try-catch语句等价于什么?

Error handling trust与try-catch语句等价于什么?,error-handling,rust,try-catch,Error Handling,Rust,Try Catch,是否可以一次处理多个不同的错误,而不是在Rust中单独处理,而无需使用其他功能?简而言之:什么是try-catch语句的等价物 类似这样的功能()早在2016年就被提出了,但我不知道它会产生什么结果,以及2019年针对此类问题的解决方案会是什么样子 例如,这样做: try { do_step_1()?; do_step_2()?; do_step_3()?; // etc } catch { alert_user("Failed to perform ne

是否可以一次处理多个不同的错误,而不是在Rust中单独处理,而无需使用其他功能?简而言之:什么是try-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(())
}
匹配do_步骤(){
好的()=>(),
_=>提醒用户(“未能执行必要的步骤”)
}
//附加功能:
fn do_步骤()->结果{
是否执行步骤1()?;
是否执行步骤2()?;
是否执行步骤3()?;
//等
好(())
}

我的程序有一个函数,它检查注册表中不同位置的不同数据值,并返回一些聚合数据。它需要在循环的其他try-catch内部使用许多try-cache语句。Rust中没有try-catch语句。最接近的方法是
操作符

但是,您不必创建函数和
match
语句来最终解析它。您可以在范围中定义闭包,并在闭包中使用
运算符。然后将抛出保存在闭包返回值中,您可以在任何地方捕获它,如下所示:

fn main() {
    let do_steps = || -> Result<(), MyError> {
        do_step_1()?;
        do_step_2()?;
        do_step_3()?;
        Ok(())
    };

    if let Err(_err) = do_steps() {
        println!("Failed to perform necessary steps");
    }
}
fn main(){
让我们做步骤=| |->结果{
是否执行步骤1()?;
是否执行步骤2()?;
是否执行步骤3()?;
好(())
};
如果让错误(_Err)=执行步骤(){
println!(“未能执行必要的步骤”);
}
}

是否可以一次处理多个不同的错误,而不是在不使用其他功能的情况下单独处理错误


是的,这是可能的。有一个板条箱用于锈病中的错误管理。使用
Failure
,您可以链接、转换和连接错误。将错误类型转换为一种常见类型后,您可以轻松捕获(处理)它。

结果可以使用
和_然后
链接Rust中的
s。所以你可以这样做:

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);
}}

还有一个不稳定的功能,叫做
try_blocks
(,)

用法示例:

#![feature(try_blocks)]

fn main() {
    // you need to define the result type explicitly
    let result: Result<(), Error> = try {
        do_step_1()?;
        do_step_2()?;
        do_step_3()?;
    };

    if let Err(e) = result {
        println!("Failed to perform necessary steps, ({:?})", e);
    }
}

fn do_step_1() -> Result<(), Error> { Ok(()) }
fn do_step_2() -> Result<(), Error> { Ok(()) }
fn do_step_3() -> Result<(), Error> { Err(Error::SomeError) }

#[derive(Debug)]
enum Error {
    SomeError,
}
#![功能(试块)]
fn main(){
//您需要显式定义结果类型
让结果:结果=尝试{
是否执行步骤1()?;
是否执行步骤2()?;
是否执行步骤3()?;
};
如果让错误(e)=结果{
println!(“未能执行必要的步骤,({:?})”,e);
}
}
fn do_step_1()->结果{Ok(())}
fn do_step_2()->结果{Ok(())}
fn do_step_3()->结果{Err(Error::SomeError)}
#[导出(调试)]
枚举错误{
有些错误,
}

只是为了插话,但故障并不是唯一有助于错误管理的板条箱。有很多,每个都有不同的焦点。请注意,您的闭包表达式正好是。