Day 5:panic! 與 unwrap(深入了解)

學習目標

  • 理解 panic! 的運作
  • 用 panic 的訊息與回溯 debug
  • 用 expect 提供更好的訊息

今日重點

panic!

fn divide(a: f64, b: f64) -> f64 {
    if b == 0.0 {
        panic!("Cannot divide by zero!");
    }
    a / b
}

panic! 會印出錯誤訊息、展開 stack,然後中止程式。預設 unwinds stack(清理資源)後崩潰。

錯誤訊息與回溯

thread 'main' panicked at src/main.rs:3:9:
Cannot divide by zero!
stack backtrace:
...

顯示觸發處的行號。回溯可用 RUST_BACKTRACE=1 看完整 call stack。

expect vs unwrap

let home = "127.0.0.1".parse().expect("IP 格式錯誤");  // 帶說明
let home = "127.0.0.1".parse().unwrap();                // 無說明

兩者遇到 Err 都 panic。expect 多帶一條自訂訊息,debug 時更清楚。

測試 panic(should_panic)

#[test]
#[should_panic(expected = "Cannot divide by zero")]
fn test_divide_by_zero() {
    divide(10.0, 0.0);   // 預期會 panic
}

練習

// 1. 跑一段會 panic 的程式,觀察錯誤訊息與行號
fn main() {
    let v = vec![1, 2, 3];
    println!("{}", v[10]);   // 越界 -> panic
}
// 2. 設 RUST_BACKTRACE=1 執行,看回溯

// 3. 寫 expect 並故意觸發 failure

自我檢查

  • 知道 panic! 的運作(印訊息、回溯、中止)
  • 能讀懂 panic 訊息的行號
  • 知道 expect vs unwrap 的差別
  • 會用 #[should_panic] 測 panic

深入連結

  • The Book 第 9 章「Unrecoverable Errors with panic!」