我正在按照YouTube 指南构建 Rust 项目。我创建了一个error.rs
文件来保存自定义错误,它看起来像这样:
#[derive(thiserror::Error, Debug)]
pub enum Error {
/// For starter, to remove as code matures.
#[error("Generic error: {0}")]
Generic(String),
}
之后我重新导出我的错误prelude.rs
// Re-export the crate Error.
pub use crate::error::Error;
// Alias Result to be the crate Result.
pub type Result<T> = core::result::Result<T, Error>;
// Generic Wrapper tuple struct for newtype pattern,
// mostly for external type to type From/TryFrom conversions
pub struct W<T>(pub T);
并创建一个将使用错误的函数:
fn foo(n: i32) -> Result<i32> {
if n == 3 {
return Error::Generic("I don'l like 3".to_string());
}
Ok(n)
}
但是当我尝试使用自定义错误时,Rust 不允许它,说我需要将它包装在一个Err
值中。为什么我在返回 时不能使用自己的错误Result
,有没有办法可以避免在这种情况下包装它?
error[E0308]: mismatched types
--> src/lib.rs:12:16
|
10 | fn foo(n: i32) -> Result<i32> {
| ----------- expected `std::result::Result<i32, error::Error>` because of return type
11 | if n == 3 {
12 | return Error::Generic("I don'l like 3".to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Result<i32, Error>`, found `Error`
|
= note: expected enum `std::result::Result<i32, error::Error>`
found enum `error::Error`
help: try wrapping the expression in `Err`
|
12 | return Err(Error::Generic("I don'l like 3".to_string()));
| ++++ +
作为澄清,YouTuber 使用以下代码解决了这个问题:
use crate::prelude::*;
use std::fs::DirEntry;
impl TryFrom<W<&DirEntry>> for String {
type Error = Error;
fn try_from(val: W<&DirEntry>) -> Result<String> {
val.0
.path()
.to_str()
.map(String::from)
.ok_or_else(|| Error::Generic(f!("Invalid path {:?}", val.0)))
}
}
因为您的返回类型不是
Result
,所以Error
它们是不同的类型。您必须返回它的变体之一Result::Ok
或Result::Err
.ok_or_else
:正如您所看到的,采用一个返回错误类型的闭包
E
,而不是Result
. 并且它将返回值包装在 中Err
,因此使用它的代码不必包装它。