macro_rules!

Rustはメタプログラミングのための強力なマクロシステムを備えています。前の章で 見たように、マクロは関数のように働き、その名前は!で終わります。しかし、関数 と違って、マクロはコンパイルされる前に、ソースコードに展開されます。また、Cの ような言語のマクロとは違い、Rustのマクロは抽象構文木に展開されるため、前処理 より強力です。そのため、予期しない優先順位によるバグが起こることはありません。

マクロはmacro_rules!マクロで作ることができます。

// シンプルなマクロ`say_hello`
macro_rules! say_hello {
    // `()`はマクロが引数を取らないことを表します。
    () => {
        // マクロはこのブロックの要素に展開されます。
        println!("Hello!");
    };
}

fn main() {
    // This call will expand into `println!("Hello");`
    say_hello!()
}

マクロはなぜ有用なのでしょうか?

  1. 同じことを繰り返さない(Don't repeat yourself, DRY)。似たような処理を複数の場所に 使いたいが、違う型であるためにまとめるのが難しいときがあります。マクロを使えば、 コードの繰り返しを避けられることがあります。(詳しくは後で)

  2. ドメイン固有言語。マクロで特有の目的のための特殊な構文が定義できます。(詳しくは 後で)

  3. 可変長引数。時々可変長の引数を取るインターフェースを書きたいときがあります。例えば println!はフォーマット文字列に従って様々な数の引数をとります。(詳しくは後で)