Rust錯誤處理

簡單的錯誤處理

要不是使用「?」,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

相關文章
相關標籤/搜索