Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

macro_rules!

Rust は、メタプログラミングを可能にする強力なマクロシステムを提供します。これまでの章で 見てきたように、マクロは関数のように見えますが、名前が感嘆符 ! で終わる点が異なります。 ただし、マクロは関数呼び出しを生成するのではなく、プログラムの残りの部分と一緒にコンパイルされる ソースコードへと展開されます。とはいえ、C や他の言語のマクロとは異なり、Rust のマクロは 文字列の前処理ではなく抽象構文木へと展開されるため、優先順位に関する予期しないバグは発生しません。

マクロは macro_rules! マクロを使って作成できます。

// これは `say_hello` という名前のシンプルなマクロです。
macro_rules! say_hello {
    // `()` は、このマクロが引数を取らないことを示します。
    () => {
        // このマクロは、このブロックの内容へと展開されます。
        println!("Hello!")
    };
}

fn main() {
    // この呼び出しは `println!("Hello!")` へと展開されます
    say_hello!()
}

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

  1. 繰り返しを避けるため。似たような機能が複数の場所で必要になるものの、 型が異なるというケースは数多くあります。多くの場合、マクロを書くことは コードの繰り返しを避ける有用な方法です。(これについては後ほど詳しく)

  2. ドメイン固有言語。マクロを使うと、特定の目的のために特別な構文を定義できます。 (これについては後ほど詳しく)

  3. 可変長インターフェイス。可変個の引数を取るインターフェイスを定義したい場合があります。 その例が println! で、これはフォーマット文字列に応じて任意の数の引数を取ることができます。 (これについては後ほど詳しく)