巨集是 Rust 程式設計師工具箱中威力強大的一環,而範例巨集則是取得這份力量的相對簡單方式。我們來寫一個吧!
巨集是什麼?維基百科是這麼描述的:
在電腦科學中,巨集(為「巨集指令」的簡稱,源自希臘文 μακρός,意思是「長」)是一種規則或模式,用來規定某個輸入序列(通常是一連串字元)應該依照既定的程序,對應到取代後的輸出序列(通常也是一連串字元)。把巨集的使用實例化(轉換)成特定序列的對應過程,稱為巨集展開。
真是精闢的說明!不過更具體地說,巨集是一種特殊的語法,讓你能在編譯期產生程式碼。巨集可以用來做編譯期計算,但更常見的用途,只是另一種將程式碼抽象化的方式。例如,你大概已經用過println!()和vec![]。它們各自接受任意數量的引數,因此無法用單純的函式來表示。另一方面,它們總是展開成一定數量、完全標準的 Rust 程式碼。如果你有興趣,可以使用 cargo expand 子命令來檢視程式碼中巨集展開的結果。
想進一步了解 Rust 的巨集,可以參考《The Rust Book》中不錯的章節。
你可以用vec![]巨集,直接在程式碼中產生任意長度的Vec。不過,Rust 並沒有內建直接產生HashMap的方法。請寫一個hashmap!()巨集來解決這個問題。
舉例來說,使用你的程式庫的人可能會寫下hashmap!('a' => 3, 'b' => 11, 'z' => 32)。這應該展開成下列程式碼:
{
let mut hm = HashMap::new();
hm.insert('a', 3);
hm.insert('b', 11);
hm.insert('z', 32);
hm
}
請注意,maplit crate提供了一個能完美解決這道練習的巨集。請自行實作你的解法,不要使用這個 crate;也請在看它的原始碼之前,先自己試著做看看。