Day 1:巨集(Macros)入門
學習目標
- 理解巨集的用途(產程式碼的程式碼)
- 用 macro_rules! 寫簡單巨集
- 認識宣告式巨集的語法
今日重點
巨集是什麼?
巨集是「寫程式的程式碼」。執行時(編譯階段)展開成 Rust 程式碼。
println!、vec!都是巨集。
陳述式巨集(macro_rules!)
macro_rules! say_hello {
() => {
println!("Hello!");
};
}
fn main() {
say_hello!(); // 展開成 println!("Hello!")
}
帶參數的巨集(match pattern)
macro_rules! create_function {
($func_name:ident) => {
fn $func_name() {
println!("You called {:?}", stringify!($func_name));
}
};
}
create_function!(foo);
create_function!(bar);
fn main() {
foo();
bar();
}
$func_name:ident表示「匹配一個識別字」。巨集會依模式展開。
重複模式
macro_rules! hello_vec {
($($item:expr),*) => {
vec![$($item),*]
};
}
fn main() {
let v = hello_vec!(1, 2, 3); // vec![1, 2, 3]
println!("{:?}", v);
}
$(...)表示「重複部分」,*表示零到多次。
練習
// 1. 寫一個 min! 巨集,取兩個數的較小者
macro_rules! min {
($x:expr, $y:expr) => {
if $x < $y { $x } else { $y }
};
}
println!("{}", min!(10, 20)); // 10
// 2. 寫一個 repeat_print!(msg, n) 印 n 次
$x:expr、$func_name:ident、$(...)* 各代表什麼。
自我檢查
- 理解巨集「展開」的機制
- 會寫 macro_rules! 基本巨集
- 認識 $item:expr / ident / 重複語法
- 知道 println!/vec! 就是巨集
深入連結
- The Book 第 19 章「Macros」