将第三方错误轻松转换为字符串

11

我有这段代码:

fn do_stuff() -> Result<i32, String> {

    let repo = git2::Repository::open(".")?;
    // ...
}

这不起作用,因为git2::Repository::open()的错误类型不是String。(是的,我在错误处理方面有些懒惰,使用字符串。这是一个很小的程序,请勿起诉我。)

error[E0277]: the trait bound `std::string::String: std::convert::From<git2::Error>` is not satisfied
  --> src/main.rs:94:13
   |
94 |    let repo = Repository::open(".")?;
   |               ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<git2::Error>` is not implemented for `std::string::String`
   |
   = help: the following implementations were found:
   = help:   <std::string::String as std::convert::From<&'a str>>
   = help:   <std::string::String as std::convert::From<std::borrow::Cow<'a, str>>>
   = note: required by `std::convert::From::from`

我尝试加入了这个:

impl std::convert::From<git2::Error> for String {
    fn from(err: git2::Error) -> Self {
        err.to_string()
    }
}

但这是不允许的,因为它没有引用此 crate 中定义的任何类型。

我知道我可能可以使用 .map_err(),但我真的希望它可以自动发生。我有点觉得我以前也做过这个工作,这有点烦人!


是的,你不能为你不拥有的类型实现你不拥有的特质。 - Shepmaster
2个回答

12
如果一个类型实现了 std::error::Error会实现Display
pub trait Error: Debug + Display {
    // ...
}

ToString特性提供了to_string方法,对于实现了Display特性的任何类型都可以使用。

因此,任何实现了Error特性的类型都可以通过to_string转换为String类型:

use git2; // 0.13.2

fn do_stuff() -> Result<i32, String> {
    let repo = git2::Repository::open(".").map_err(|e| e.to_string())?;
    unimplemented!()
}

你会如何填写 map_err(...) 中的 ...,使其使用 to_string() 但不需要显式地使用闭包 (|e| ...)?也就是说,我想知道在 这个答案 中它会是什么样子。 - Sean Leather
1
@SeanLeather 在 Rust 2018 中(在 Rust 1.31 的本周末可用),您可以使用 .as_ref().map_err(git2::Error::to_string) - Shepmaster
@SeanLeather 请问能否帮忙看一下Rust2018版指南非词法生命周期是什么?这个问题吗? - Shepmaster
很遗憾,我不清楚非词汇生命周期是如何允许从.map_err(|e| e.to_string())更改为.as_ref().map_err(git2::Error::to_string)的。 - Sean Leather
@SeanLeather,这只是为了让一行代码适应屏幕大小,否则就需要将其分成两行。使用as_ref可以使Option中的值成为一个引用。 - Shepmaster

3

事实证明,关于这个问题在《Rust书籍》中有一点点内容。它不允许你转换成String,但显然所有的Error类型都可以转换成Box<Error>,所以我就用后者代替String了。这样更简洁。


4
此外,?try! 在其 Error 参数上调用 From::from,这意味着你可以使用 Box<Error>? 将各种错误轻松地合并为通用错误,如果这是你想要的。 - Josh Lee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接