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!」