如何捕获 Rust 中的所有错误?

Eka*_*Eka 2 error-handling rust

我是 Rust 的新手,我写了一个函数,它返回一个带有 Box dyn 错误的结果。

use std::error::Error;

fn func<T>(val: T) -> Result<(), Box<dyn Error>>
where
    T: std::fmt::Debug,
{
    println!("{:?}", val);    
    Ok(())
}

fn main() {
    func("hello world");
}
Run Code Online (Sandbox Code Playgroud)

在这里,我没有在函数中编写任何错误逻辑,func但它仍然有效。上面的代码会自动捕获所有错误吗?类似于python的

try:
  # Run the code
except:
  # Catch all the errors
Run Code Online (Sandbox Code Playgroud)

Rust 中是否有任何通用的错误捕获方式?

Mic*_*son 6

如果你运行cargo clippy这个,你会得到以下警告:

warning: unused `std::result::Result` that must be used
  --> src/main.rs:12:5
   |
12 |     func("hello world");
   |     ^^^^^^^^^^^^^^^^^^^^
   |
Run Code Online (Sandbox Code Playgroud)

这告诉你,虽然func返回一个Result可能是错误的,但你没有对它做任何事情。

您需要处理错误 - 最简单的方法是更改​​ main 以返回错误:

fn main() -> Result<(), Box<dyn Error>> {
    func("hello world")?; // If this fails, the `?` makes main return it
    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

现在func失败了,main也会失败。

为了看到这一点,我们需要一个错误类型 - 实现起来有点乏味(例如,请参阅此处了解详细信息)。相反,我将转换为anyhow用于错误。

use anyhow::{anyhow, Result};

fn func<T>(val: T) -> Result<()>
where
    T: std::fmt::Debug,
{
    println!("{:?}", val);    
    Err(anyhow!("BANG"))
}

fn main() -> Result<()> {
    func("hello world")?;
    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

现在func返回一个错误,并运行二进制输出:

"hello world"
Error: BANG
Run Code Online (Sandbox Code Playgroud)

如果你不想让你的应用程序退出的错误,或者不希望它退出这种方式,那么你需要从处理结果func自己

use anyhow::{anyhow, Result};

fn func<T>(val: T) -> Result<()>
where
    T: std::fmt::Debug,
{
    println!("{:?}", val);    
    Err(anyhow!("BANG"))
}

fn main() {
    match func("hello world") {
      Err(e) => println!("an error: {:?}", e), //<= error handling
      Ok(_) => println!("func was OK"),
    }
}
Run Code Online (Sandbox Code Playgroud)

这将输出:

"hello world"
an error: BANG
Run Code Online (Sandbox Code Playgroud)