将错误消息返回到期望“ Box <dyn Error>”的函数

时间:2019-10-15 11:08:08

标签: error-handling rust

我是Rust的新手,正在尝试传播要在调用函数中处理的错误。从正式的rust书籍中,我读到结果'Box '用来表示捕获任何类型的错误,但是我读得不够多,无法理解它的实际工作方式。

我有一个函数叫做:

fn foo() -> Result<String, Box<dyn Error>> {
    Command::new("an_executable")
        .args(&["-p", path])
        .output()?;
    if condition {
        return Err("Error...");
    }
    // Do stuff, return String 
}

因此有人可以解释如果该返回类型满足条件,我应该如何返回错误。我必须更改返回类型还是只返回其他内容。在这种情况下,RUST标准是什么?

当前的编译错误是Err(“ Error ...”)与返回类型不匹配

1 个答案:

答案 0 :(得分:4)

让我们从最小限度地复制您的问题开始吧

use std::error::Error;

fn foo() -> Result<String, Box<dyn Error>> {
    Err("Error...")
}

返回的错误是:

error[E0308]: mismatched types
 --> src/lib.rs:4:9
  |
4 |     Err("Error...")
  |         ^^^^^^^^^^ expected struct `std::boxed::Box`, found reference
  |
  = note: expected type `std::boxed::Box<dyn std::error::Error>`
             found type `&'static str`

这是说函数签名希望您返回包含Err的{​​{1}},但是实际上您返回了Box。因此,我们将字符串装箱:

&str

现在,您会收到一个新错误:

use std::error::Error;

fn foo() -> Result<String, Box<dyn Error>> {
    Err(Box::new("Error..."))
}

同样,问题是您返回的类型与函数的签名不匹配-期望该框包含实现error[E0277]: the trait bound `&str: std::error::Error` is not satisfied --> src/lib.rs:4:9 | 4 | Err(Box::new("Error...")) | ^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `&str` | = note: required for the cast to the object type `dyn std::error::Error` 特征的内容,但是如果您look at the docs,将会注意到Error不是实现它的类型之一。您需要将字符串包装成确实实现&str的类型:

Error

此代码可以编译!

编辑:我刚刚发现自己有一种更简单的方法-use std::error::Error; use std::fmt; #[derive(Debug)] struct StrError<'a>(&'a str); // Error doesn't require you to implement any methods, but // your type must also implement Debug and Display. impl<'a> Error for StrError<'a> {} impl<'a> fmt::Display for StrError<'a>{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Delegate to the Display impl for `&str`: self.0.fmt(f) } } fn foo() -> Result<String, Box<dyn Error>> { Err(Box::new(StrError("Error..."))) } 的{​​{1}}实现,因此,如果您调用它,则可以避免上面的样板。不过,相同的事情或多或少正在发生,我希望更详细的解释会有所帮助!。

From<&str>