理解 Rust 中的不可恢復錯誤和可恢復錯誤
在 Rust 中,錯誤分為兩類:可恢復錯誤和不可恢復錯誤。對于可恢復錯誤,我們使用 Result 枚舉,而對于不可恢復錯誤,我們使用 panic! 宏。
Rust 中的不可恢復錯誤:Panic 宏
在 Rust 中,不可恢復錯誤指的是程序無法安全繼續執行的情況。這些錯誤通過 panic! 宏來處理。當 panic! 被觸發時,應用程序將停止執行,并展開棧,這通常會導致進程終止。
示例:索引越界
例如,如果你嘗試訪問超出向量范圍的索引,將會引發 panic:
let names = vec!["Sunny", "Hugo", "Charlie"];
names[10]; // 這將導致 panic
// thread 'main' panicked at src/main.rs:5:10:
// index out of bounds: the len is 3 but the index is 10
在數據無效或無法從錯誤中恢復的情況下,你可以手動調用 panic! 宏:
panic!("The app cannot continue, please fix data");
// thread 'main' panicked at src/main.rs:2:5:
// The app cannot continue, please fix data
不可恢復錯誤總結
當程序因關鍵問題(如數據無效或違反程序假設的情況)而無法繼續時,就會發生不可恢復錯誤。panic! 宏用于在這些錯誤發生時停止程序執行。
Rust 中的可恢復錯誤:Result 枚舉
與此相對,可恢復錯誤是指程序可以處理并繼續運行的錯誤。這類錯誤通過 Result 枚舉來處理。
Result 枚舉有兩個變體:
- Ok(T): 表示成功,包含結果值
- Err(E): 表示失敗,包含錯誤值
enum Result<T, E> {
Ok(T),
Err(E)
}
示例:文件未找到
如果你嘗試打開一個不存在的文件,可以在不崩潰程序的情況下處理錯誤。以下是使用 Result 枚舉和 match 語句的示例:
use std::fs::File;
fn main() {
let file = File::open("bad_file.png");
match file {
Ok(f) => {
println!("File found {:?}", f);
},
Err(e) => {
println!("File not found {:?}", e);
}
}
println!("App is still running...");
}
// File not found Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." }
// App is still running...
如你所見,程序沒有 panic,而是通過打印錯誤信息來處理錯誤,應用程序繼續運行。
錯誤處理的輔助方法
你可能見過 Rust 中的 unwrap() 方法,并想知道它的作用。unwrap() 是處理 Result 類型的快捷方式,但存在風險。如果結果是 Ok,unwrap() 返回值。然而,如果結果是 Err,unwrap() 將導致 panic。
你可以用 unwrap() 替換 match 語句:
let file = File::open("bad_file.png").unwrap();
// thread 'main' panicked at src/main.rs:4:43:
// called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." }
如你所見,如果文件未找到,程序將 panic 并停止運行。
第二個選項是 expect()。
expect() 方法類似于 unwrap(),但允許你提供自定義錯誤信息。如果你希望提供更多關于錯誤的上下文,而不僅僅依賴于默認的 panic 信息,這將非常有用。
let file = File::open("bad_file.png").expect("Ooops something went wrong");
// thread 'main' panicked at src/main.rs:4:43:
// Ooops something went wrong: Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." }
結論
- 不可恢復錯誤:在程序無法繼續的情況下使用 panic!。這些錯誤會停止程序的執行。
- 可恢復錯誤:使用 Result 枚舉來處理程序可以繼續的錯誤。你可以使用 match、unwrap() 或 expect() 來處理這些錯誤。