如何正确使用Result?
How to use Result correctly?
我正在尝试 return 如果一切顺利,如果出现问题,return 错误代码,但它不起作用:
mod reader {
/*uses*/
enum FileError {
FileNotFound,
PgnInvalid,
}
fn read_game(file_path: &str) -> Result<BufferedReader<File>, FileError> {
let f = File::open(file_path)?;
match f {
Err(e) => FileError::FileNotFound,
Ok(file) => {
let r = BufferedReader::new(file)?;
match r {
Err(e) => FileError::PgnInvalid,
Ok(reader) => reader,
}
}
}
}
}
我收到这个错误:
mismatched types [E0308] expected `Result<BufferedReader<File>, FileError>`, found `FileError`
Result
是一个枚举,它可以是以下两种变体之一:Ok(..)
或 Err(..)
。当 returning 一个结果时,您需要指定您 returning 的变体。现在你只是 returning FileError
或 BufferedReader<File>
导致匹配武器的类型冲突,并且还与 return 类型冲突。相反,您可以做的是使用 Result
的 map_err
函数映射错误类型,并将 ?
(读作“try”)运算符早期应用于 return 错误遇到错误时的变体。
fn read_game(file_path: &str) -> Result<BufferedReader<File>, FileError> {
let f = File::open(file_path).map_err(|_| FileError::FileNotFound)?;
BufferedReader::new(f).map_err(|_| FileError::PgnInvalid)
}
您可以在有关枚举的书中阅读有关结果 here, and I'd also recommend checking out the section 的更多信息。
要return一个Result
,您需要return它的枚举值之一,Ok
或Err
。所以你的代码可能是:
fn read_game(file_path: &str) -> Result<BufferedReader<File>, FileError> {
let f = File::open(file_path);
match f {
Err(e) => Err(FileError::FileNotFound),
Ok(file) => {
let r = BufferedReader::new(file);
// BufferedReader::new does not return a `Result`.
// Wrap the reader in `Ok` to return a `Result`.
Ok(r)
}
}
}
作为快捷方式,?
运算符会为您解包任何 Ok
值和 returns 任何 Err
值。所以你可以添加 ?
并删除 match
以获得这个几乎可以工作的代码:
fn read_game(file_path: &str) -> Result<BufferedReader<File>, FileError> {
let f = File::open(file_path)?;
let r = BufferedReader::new(file);
Ok(r)
}
此代码的问题是 returned Result
不支持 std::io::Error
(来自 open
的错误类型)。您可以 return a Result<BufferedReader<File>, std::io::Error>
或者您可以将错误类型映射到您支持的类型:
fn read_game(file_path: &str) -> Result<BufferedReader<File>, FileError> {
let f = File::open(file_path).map_err(|_| FileError::FileNotFound)?;
let r = BufferedReader::new(f);
Ok(r)
}
我正在尝试 return 如果一切顺利,如果出现问题,return 错误代码,但它不起作用:
mod reader {
/*uses*/
enum FileError {
FileNotFound,
PgnInvalid,
}
fn read_game(file_path: &str) -> Result<BufferedReader<File>, FileError> {
let f = File::open(file_path)?;
match f {
Err(e) => FileError::FileNotFound,
Ok(file) => {
let r = BufferedReader::new(file)?;
match r {
Err(e) => FileError::PgnInvalid,
Ok(reader) => reader,
}
}
}
}
}
我收到这个错误:
mismatched types [E0308] expected `Result<BufferedReader<File>, FileError>`, found `FileError`
Result
是一个枚举,它可以是以下两种变体之一:Ok(..)
或 Err(..)
。当 returning 一个结果时,您需要指定您 returning 的变体。现在你只是 returning FileError
或 BufferedReader<File>
导致匹配武器的类型冲突,并且还与 return 类型冲突。相反,您可以做的是使用 Result
的 map_err
函数映射错误类型,并将 ?
(读作“try”)运算符早期应用于 return 错误遇到错误时的变体。
fn read_game(file_path: &str) -> Result<BufferedReader<File>, FileError> {
let f = File::open(file_path).map_err(|_| FileError::FileNotFound)?;
BufferedReader::new(f).map_err(|_| FileError::PgnInvalid)
}
您可以在有关枚举的书中阅读有关结果 here, and I'd also recommend checking out the section 的更多信息。
要return一个Result
,您需要return它的枚举值之一,Ok
或Err
。所以你的代码可能是:
fn read_game(file_path: &str) -> Result<BufferedReader<File>, FileError> {
let f = File::open(file_path);
match f {
Err(e) => Err(FileError::FileNotFound),
Ok(file) => {
let r = BufferedReader::new(file);
// BufferedReader::new does not return a `Result`.
// Wrap the reader in `Ok` to return a `Result`.
Ok(r)
}
}
}
作为快捷方式,?
运算符会为您解包任何 Ok
值和 returns 任何 Err
值。所以你可以添加 ?
并删除 match
以获得这个几乎可以工作的代码:
fn read_game(file_path: &str) -> Result<BufferedReader<File>, FileError> {
let f = File::open(file_path)?;
let r = BufferedReader::new(file);
Ok(r)
}
此代码的问题是 returned Result
不支持 std::io::Error
(来自 open
的错误类型)。您可以 return a Result<BufferedReader<File>, std::io::Error>
或者您可以将错误类型映射到您支持的类型:
fn read_game(file_path: &str) -> Result<BufferedReader<File>, FileError> {
let f = File::open(file_path).map_err(|_| FileError::FileNotFound)?;
let r = BufferedReader::new(f);
Ok(r)
}