← 解説「macro_rules! — 宣言的マクロ」に戻る
サンプルコードで身につける: macro_rules! — 宣言的マクロ
解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。
1引数なしの最小マクロ
() => { ... } という1つの規則だけを持つ、もっとも素朴な宣言的マクロです。say_hello!() と書いた場所が、展開後は中身の println! にそっくり置き換わります。「マクロ呼び出し = コードの置き換え」という基本イメージをここでつかんでください。
Rust
2式を1つ受け取る — $x:expr
$x:expr は「式を1つ」に一致するパターンで、一致した式が展開先の $x にそのまま埋め込まれます。square!(2 + 3) のように式を渡しても1つのかたまりとして扱われ、正しく 25 になります。関数と違って引数に型を書かない点にも注目してください。
Rust
3複数の規則 — 引数の形で分岐
macro_rules! には match のように規則を複数並べられ、呼び出しの形に最初に一致した規則で展開されます。引数なし・1個・2個でそれぞれ別のコードを生成でき、関数のオーバーロードがない Rust で「引数の形ごとの定義」ができる数少ない手段です。
Rust
4繰り返し — 任意個の式を畳み込む
$( $x:expr ),* は「カンマ区切りの式0個以上」に一致し、展開側の $( total += $x; )* が一致した個数ぶん繰り返されます。引数の個数が自由な sum! は関数では書けず、マクロならではの形です。vec! が任意個の初期値を取れるのも同じ仕組みです。
Rust
5ログマクロ — レベル付き出力を共通化
固定メッセージだけの呼び出しと、追加の値を任意個並べる呼び出しを、2つの規則で受けるログマクロです。複数規則と繰り返しという、このレッスンで学んだ道具の組み合わせでできています。「毎回同じ前置きを書く」というログ出力の繰り返しをマクロが吸収する、実務での典型的な動機です。
Rust