文章目錄
- 簡介
- 錯誤匹配
Rust基礎教程: 初步? 所有權? 結構體和枚舉類? 函數進階? 泛型和特征? 并發和線程通信? cargo包管理? 可空類型Option
Rust進階教程: 用宏實現參數可變的函數? 類函數宏
簡介
Rust中沒有提供類似try…catch之類的分支語句塊,而是提供了Result這種數據類型,用于處理錯誤的返回值。和Option類似,Result的實質也是一種枚舉類型
enum Result<T, E> {Ok(T),Err(E),
}
下面做一個簡單的示例,用Result類型的返回值,來構造一個除法函數,并表示x/0這種問題
// res.rs
fn div_err(x:f32, y:f32) -> Result<f32, String>{if y==0.0{ Err("DIV BY ZERO".to_string()) } else{ Ok(x/y) }
}fn main(){println!("5/3={:?}", div_err(5.0,3.0));println!("5/0={:?}", div_err(5.0,0.0));
}
運行結果如下
>res.exe
5/3=Ok(1.6666666)
5/0=Err("DIV BY ZERO")
Rust有一個值得注意的性質,即未處理的Result,會在編譯時提出警告,比如把main函數改成下面的形式,那么編譯時會給出Result必須被使用的警告。
fn main(){div_err(5.0,3.0);
}
錯誤匹配
考慮到Result的本質是枚舉類型,所以其常規的處理方式,也就是使用match匹配,相應地,Result也支持un_wrap方法,當Result的返回值是Err時輸出直接報錯。但另一方面,Result支持多種錯誤的設置,所以從報錯的角度來說,功能顯然是更全面的。
仍以除法為例,盡管除數為0時一定要報錯,但形如 x / 0 x/0 x/0和 0 / 0 0/0 0/0顯然是兩種不同的錯誤。如果為實數添加一個無窮大,那么實數域就可以映射到一個圓形上面,從而 x / 0 x/0 x/0就可以等于 ∞ \infty ∞,但 0 / 0 0/0 0/0仍然是錯的。
下面就針對這兩種不同的情況,為其設置錯誤。
fn div_err(x:f32, y:f32) -> Result<f32, String>{if y==0.0{if x==0.0{ Err("DIV ERROR".to_string())}else { Err("INF ERROR".to_string()) }} else{Ok(x/y)}
}fn div_print(x:f32, y:f32){match div_err(x, y){Ok(res) => println!("{}/{}={}", y, x, res),Err(res) => println!("{}", res)}
}fn main(){div_print(5.0, 3.0);div_print(5.0, 0.0);div_print(0.0, 0.0);
}
運行結果如下
>res.exe
3/5=1.6666666
INF ERROR
DIV ERROR