the*_*e88 10 error-handling rust
我是 Rust 的新手,正在尝试传播要在调用函数中处理的错误。从官方 Rust 书中,我读到 Result 'Box< dyn Error>' 用于表示捕获任何类型的错误,但我读得还不够深入,无法理解它的实际工作原理。
我有一个函数叫:
fn foo() -> Result<String, Box<dyn Error>> {
Command::new("an_executable")
.args(&["-p", path])
.output()?;
if condition {
return Err("Error...");
}
// Do stuff, return String
}
Run Code Online (Sandbox Code Playgroud)
因此,有人可以解释如果该返回类型满足条件,我应该如何返回错误。我是否必须更改返回类型或只返回不同的内容。在这种情况下,RUST 标准是什么?
当前编译错误是 Err("Error...") 与返回类型不匹配
Joe*_*lay 23
让我们专注于您的问题的绝对最小再现:
use std::error::Error;
fn foo() -> Result<String, Box<dyn Error>> {
Err("Error...")
}
Run Code Online (Sandbox Code Playgroud)
此代码返回的错误是:
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`
Run Code Online (Sandbox Code Playgroud)
这是说函数签名希望您返回一个Err包含 a Box<dyn Error>,但您实际上返回了一个Err包含 a &str。由于类型不对齐,编译器会抛出错误。
解决这个问题的最简单方法是使用Intotrait,它实现了&str和之间的转换Box<dyn Error>:
use std::error::Error;
fn foo() -> Result<String, Box<dyn Error>> {
Err("Error...".into())
// `Err(Box::<dyn Error>::from("Error..."))` would also work, but is more ugly!
}
Run Code Online (Sandbox Code Playgroud)
您可能仍然想知道这个神奇的.into()调用在幕后到底做了什么。
首先,让我们看看会发生什么,如果我们只是Box在&str:
use std::error::Error;
fn foo() -> Result<String, Box<dyn Error>> {
Err(Box::new("Error..."))
}
Run Code Online (Sandbox Code Playgroud)
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`
Run Code Online (Sandbox Code Playgroud)
同样,这不起作用,因为类型不对齐 - 它期望Box包含实现Error特征的东西,但是如果您查看 docs,您会注意到它&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...")))
}
Run Code Online (Sandbox Code Playgroud)
这段代码可以编译,基本上就是impl Into<Box<dyn Error>> for &str引擎盖下的内容:)
| 归档时间: |
|
| 查看次数: |
3172 次 |
| 最近记录: |