Day 2:自訂錯誤與 From 轉換
學習目標
- 定義你自己的錯誤型別
- 用 From trait 自動轉換底層錯誤
- 建立多層錯誤的統一入口
今日重點
自訂錯誤型別
use std::io;
#[derive(Debug)]
enum AppError {
Io(io::Error),
Parse(String),
NotFound(String),
}
實作 From 自動轉換
impl From<io::Error> for AppError {
fn from(error: io::Error) -> Self {
AppError::Io(error)
}
}
有了
From<io::Error>,原本回傳io::Error的函式用?時,會被自動.into()成AppError。
Display(友善錯誤訊息)
impl std::fmt::Display for AppError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
AppError::Io(e) => write!(f, "IO error: {}", e),
AppError::Parse(msg) => write!(f, "Parse error: {}", msg),
AppError::NotFound(msg) => write!(f, "Not found: {}", msg),
}
}
}
impl std::error::Error for AppError {} // 讓它成為標準錯誤
使用統一錯誤
fn read_file(path: &str) -> Result<String, io::Error> {
std::fs::read_to_string(path)
}
fn parse_config(path: &str) -> Result<String, AppError> {
let contents = read_file(path)?; // io::Error 自動轉 AppError::Io
if contents.is_empty() {
return Err(AppError::Parse("Config is empty".to_string()));
}
Ok(contents)
}
練習
- 定義
AppError,加入一個Network(String)變體。 - 實作
From<std::net::AddrParseError>。 - 寫一個函式同時
?傳 io 錯和 parse 錯到 AppError。
自我檢查
- 能定義自己的多變體錯誤
- 會用 From 讓
?自動轉型 - 能實作 Display 與 std::error::Error
- 理解「用統一的錯誤型別包裹多種錯誤」的模式
深入連結
- The Book 第 9 章「Defining a Type of Error / To panic? or not」