Day 2:建立可重用巨集範例

學習目標

  • 練習不同 fragment types
  • 用巨集做程式碼生成
  • 了解巨集的侷限

今日重點

常見 fragment type 速查

片段 代表
$x:expr 一個表達式
$n:ident 一個識別字(變數/函式名)
$t:ty 一個型別
$lit:literal 一個字面值
$pat:pat 一個模式

生成 enum 變體的巨集

// 生成一個包含多個變體、全都能 Debug 的 enum
macro_rules! simple_enum {
    ($name:ident { $($variant:ident),* }) => {
        #[derive(Debug)]
        enum $name {
            $($variant),*
        }
    };
}

simple_enum!(Status { Running, Stopped, Error });

fn main() {
    let s = Status::Running;
    println!("{:?}", s);
}

巨集的侷限

  • 語法脆弱、錯誤訊息不直觀
  • 進階功能(如烹調 AST)需要 procedure macro(proc macro,另一套 API)
  • 過度使用會降低可讀性

原則:解決重複的平凡模式時用巨集,複雜規則用 proc macro 或函式。

練習

// 1. 寫一個 make_getters! 巨集,為 struct 生成對每個欄位的 getter
// 2. 寫一個 variadic 巨集 sum_all! 接受 0..n 個數相加

思考:怎樣的程式碼適合用巨集重構?有沒有其實用函式就夠了?

自我檢查

  • 認識 fragment types
  • 能寫生成 enum / 重複模式的巨集
  • 知道巨集的侷限
  • 判斷何時該用巨集

深入連結

  • The Book 第 19 章+「The Little Book of Rust Macros」