rec*_*x51 5 error-handling type-systems rust
如果条件为真,我想从函数返回错误:
use std::error::Error;
pub fn run() -> Result<(), Box<Error>> {
// -- snip ---
if condition {
// return error
}
// -- snip --
Ok(())
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
我可能没有类型系统的基础知识,但是在我所看到的所有地方,人们都在使用?
运算符,所以我无法弄清楚要返回哪种类型。
jim*_*mis 10
我是 Rust 的新手,但这是我返回自定义错误的肮脏技巧,因为该函数设置为 return Result<(), Box<dyn Error>>
:
fn serve(config: &Config, stream: TcpStream) -> Result<(), Box<dyn Error>> {
// ...
if request_is_bad() {
// This returns immediately a custom "Bad request" error
Err("Bad request")?;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
Error
是一个特征,您想返回一个特征对象(请注意dyn
关键字),因此您需要实现此特征:
use std::error::Error;
use std::fmt;
#[derive(Debug)]
struct MyError(String);
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "There is an error: {}", self.0)
}
}
impl Error for MyError {}
pub fn run() -> Result<(), Box<dyn Error>> {
let condition = true;
if condition {
return Result::Err(Box::new(MyError("Oops".into())));
}
Ok(())
}
fn main() {
if let Err(e) = run() {
println!("{}", e); // "There is an error: Oops"
}
}
Run Code Online (Sandbox Code Playgroud)
Debug
,Display
然后Error
为此,Err
变体Result
。我建议您使用失败来删除所有错误样板:
#[derive(Fail, Debug)]
#[fail(display = "There is an error: {}.", _0)]
struct MyError(String);
Run Code Online (Sandbox Code Playgroud)
-
请注意,如果期望使用an Error
,则可以返回所需的任何类型,只要它实现即可Error
。这包括中的错误类型std
。
小智 7
Box<dyn Error>
对于实现它的类型来说很方便:
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
Err("March")?
}
Run Code Online (Sandbox Code Playgroud)
但令人惊讶的是,它并不适用于所有类型:
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
// the trait `std::error::Error` is not implemented for `{integer}`
Err(9)?
}
Run Code Online (Sandbox Code Playgroud)
作为解决方法,您可以使用我所说的错误格式习惯用法:
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
Err(format!("{}", 9))?
}
Run Code Online (Sandbox Code Playgroud)
请注意,这有很多变体,例如,对于文字,您可以这样做:
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
Err(concat!(9))?
}
Run Code Online (Sandbox Code Playgroud)
而且,您甚至可能不需要使用Box<dyn Error>
:
fn main() -> Result<(), String> {
Err(concat!(9))?
}
Run Code Online (Sandbox Code Playgroud)
在您通常不需要它的情况下它也很有用。例如,下面的示例可以在没有它的情况下工作,但它很有用,因为它将文件名添加到错误中,而该错误通常不会显示:
use std::fs;
fn main() -> Result<(), String> {
let s = "a.rs";
match fs::read_to_string(s) {
Ok(v) => print!("{}", v),
// normal message is just: The system cannot find the file specified
Err(v) => Err(format!("{} {}", s, v))?
}
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3491 次 |
最近记录: |