要不是使用“?”,Rust的错误处理会显得有些不够灵巧。要使用“?”咱们须要声明返回值类型为Result类型,这种类型能够包含任何具有std::error::Error
特征从而能够转换为Bax<Error>
类型的错误类型。
拿咱们须要处理IO错误和字符串转换为数字错误举例:html
use std::fs::File; use std::io::prelude::*; use std::error::Error; fn run(file: &str) -> Result<i32, Box<Error>> { let mut file = File::open(file)?; let mut contents = String::new(); file.read_to_string(&mut contents)?; Ok(contents.trim().parse()?) }12345678910
这里使用了俩个"?"处理可能发生的IO错误:打开文件错误和读取内容为string错误。
使用了一个“?”处理可能发生的类型转换错误。
最后咱们将结果包装为Ok
类型。Rust能够中返回值中判断出parse
的结果为i32
类型。
简化Result
类型的声明比较容易,咱们能够定义一个本身的Result类型,好比:git
type BoxResult<T> = Result<T, Box<Error>>1
可是,咱们程序还须要自定义Error
类型,那咱们就须要作些其余工做:github
Debug
特征Display
特征Error
特征就像这样:app
//error1.rs use std::error::Error; use std::fmt; #[derive(Debug)] struct MyError { details: String } impl MyError { fn new(msg: &str) -> MyError { MyError{details: msg.to_string()} } } impl fnt::Display for MyError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Reuslt { write!(f, "{}", self.details) } } impls Error for MyError { fn description(&self) -> &str { &self.details } } //一个测试咱们自定义错误的函数 fn raises_my_error(yes: bool) -> Result<(), MyError> { if yes { Err(MyError::new("borked")) } else { Ok(()) } }1234567891011121314151617181920212223242526272829303132333435
输入Result<T, MyError>
比较麻烦,因此不少模块都定义了本身的Result类型,这样能够少敲几下键盘。好比IO模块定义了io::Reust<T>
代替Result<T, io::Error>
使用。
在下面的例子中演示的是怎么处理String类型转化为浮点数类型可能出现错误的状况。
如今咱们知道使用"?"能够方便的把有错误的表达式转换为Err返回。这种转换是经过From
特征实现的。
你能够继续使用这种方便的转换,这在一些比较简单的应用中是个不错的选择,接下来咱们演示的场景会复杂一些。ParseFloatError
实现了Error
特征,因此它具有description()
方法。ide
use std::num::ParseFloatError; impl From<ParseFloatError> for MyError { fn from(err: ParseFloatError) -> Self { MyError::new(err.description()) } } fn parse_f64(s: &str, yes: bool) -> Result<f64, MyError> { raise_my_error(yes)?; let x: f64 = s.parse()? Ok(x) } fn main() { println!(" {:?}", parse_f64("42", false)); println!(" {:?}", parse_f64("42", true)); println!(" {:?}", parse_64("?42", false)); }123456789101112131415161718
执行结果会是这样:函数
Ok(42)
Err(MyError {details: “borked”})
Err(MyError {details: “invalid float literal”})测试
原文地址spa