接下來我們要來介紹 Macro 了!
Macro 主要是用一小段程式碼來寫另一段的程式碼,這個概念跟 Meta Programming 很像,主要是避免寫過多重複的程式碼
這聽起來跟 Function 蠻像的,不過 Macro 有 Function 沒有的特性,能應用的範圍更廣,我們今天也會一併介紹!
剛剛提到 Macro 的概念跟 Meta Programming 很像,那 Meta Programming 又是什麼?
Meta Programming 主旨是在減少重複性高且繁瑣的程式碼,以更讓電腦看得懂的前提出發,將程式碼寫的更精簡,且更好維護
不過缺點在於,無法兼具易讀性,當我們寫出來的程式碼越精簡,有可能對於開發者來說會越難懂
這樣看起來 Macro 跟 Function 好像蠻像的,兩個都是將重複的事情整理起來,
不過 Macro 能做到的事情比 Function 更多,不僅可以傳遞多個參數,參數的型別也不會被限制
Macro 在編譯前就會先展開到執行緒中,而 Function 則是走一般的編譯流程並且執行
我們可以來客製化 Macro ,將重複性高的程式碼變成一個巨集,並重複使用它
macro_rules!
可以用來自定義的 macro
()
裡面可以放參數,稍後會有範例
{}
裡面的程式碼會在編譯前擴展到呼叫的 block 中
fn main() {
macro_rules! introduction {
() => {
println!("My name is Ning!")
};
}
introduction!()
}
> cargo run
My name is Ning!
$message
$ 是 macro 的參數符號expr
指的是目前參數是什麼:
為標示符號,表示我目前這個參數是什麼
除了 expr
還有其他類型等等
stmt
一個句子,例如 let x = 5;pat
一個模式,match
、if let
就可以用模式expr
一個表達式,會返回值的,像是函式、運算式ty
一種類型,像是 i32
、 &str
fn main() {
macro_rules! introduction {
($message:expr) => {
println!("My name is {}!", $message)
};
}
introduction!("Ning")
}
macro 放置到 main 中,在編譯前會展開,並且將參數帶入,會做出 println!("My name is {}!", "Ning")
的程式碼
> cargo run
My name is Ning!
macro 可以傳遞多個參數,並且執行多次
要讓他重複執行的話,我們需要使用 $(...)*
符號,而 ...
可以是一個 expr
或是一個 pat
,或其他標示符號也可以
我們可以看到下方的 ()
第二個參數為 *
這表示他會重複 $()
裡面的參數
fn main() {
macro_rules! introduction {
($($message:expr), *) => {
$(
println!("My name is {}!", $message);
)*
};
}
introduction!("Ning", "Jane", "Amy");
}
當我們編譯完並執行時,傳了三次參數進去,他就會跑三次結果出來
> cargo run
My name is Ning!
My name is Jane!
My name is Amy!