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(())
}
1. 練習用「回傳 Result 的 main」+ ?。 2. 練習為「測試」寫一個使用 unwrap 的簡單函式。

自我檢查

  • 能判斷何時用 Result、何時 panic
  • 知道 unwrap/expect 適用的場合
  • 會用回傳 Result 的 main
  • 建立「庫回傳 Result、應用負責決策」的觀念

深入連結

  • The Book 第 9 章「To panic! or Not to panic!」