Day 4:錯誤處理最佳實踐
學習目標
- 分清「可回復錯誤(Result)」與「不可回復錯誤(panic)」
- 知道什麼時候該用哪一種
- 建立好的錯誤處理習慣
今日重點
Result vs panic 的決策
Rule of thumb:可預期、可回復的失敗 → 用
Result;程式的 bug、不可回復的失敗 →panic!。
| 情境 | 作法 |
|---|---|
| 檔案不存在 | Result(呼叫端決定) |
| 使用者輸入格式錯 | Result |
| 網路連不到 | Result(可能要 retry) |
| 陣列越界(程式 bug) | panic |
| 不變量被破壞(assert) | panic |
unwrap / expect 的時機
// 可以:你知道不會失敗(硬編碼字面值)
let home: std::net::IpAddr = "127.0.0.1".parse().unwrap();
// 可以:程式員錯誤需求得明確說明
let file = File::open("config.toml").expect("config.toml 必須存在");
// 不好:真實輸入可能失敗時 unwrap
// let file = File::open(user_input).unwrap(); // 會崩潰
建議模式
- 庫(library):回傳
Result,不要把決定權吃掉 - 應用(binary)的 main:可用
Result+?,讓錯誤顯示並退出 - 測試:大量使用
unwrap()合理(測試假設必須成功)
練習
use std::fs;
fn load_file(path: &str) -> Result<String, std::io::Error> {
fs::read_to_string(path)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 使用 ?,失敗就把錯誤印在輸出並回傳
let content = load_file("notes.txt")?;
println!("{}", content);
Ok(())
}
?。
2. 練習為「測試」寫一個使用 unwrap 的簡單函式。
自我檢查
- 能判斷何時用 Result、何時 panic
- 知道 unwrap/expect 適用的場合
- 會用回傳 Result 的 main
- 建立「庫回傳 Result、應用負責決策」的觀念
深入連結
- The Book 第 9 章「To panic! or Not to panic!」