宣言的マクロ(`macro_rules!`)
繰り返し現れるコードパターンを抽象化し、コンパイル時にコードを生成する宣言的マクロの書き方を学びます。
「宣言的マクロ(`macro_rules!`)」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン1/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全3レッスンが含まれています。
Rust のマクロとは
マクロは、コードを書くコードを記述する仕組みです。関数に似ていますが、値ではなく構文木(コードの構造)を対象に処理します。
- 繰り返しの多いコードを抽象化できます。
- Rust 内でドメイン固有言語(DSL)を利用できるようにします。
- コンパイル時に実行され、コンパイル前に通常の Rust コードへ展開されます。
宣言的マクロの構文
Rust の宣言的マクロでは、macro_rules! キーワードを使用します。これは、特定の Rust コードのパターンに一致する一連のルールを定義します。
コード片に対するパターンマッチングだと考えるとよいでしょう。コンパイラーがマクロ呼び出しを見つけると、入力が定義済みのルールのいずれかに一致するかを調べます。
最初の `macro_rules!`
あいさつを表示する、とても簡単なマクロを作ってみましょう。macro_rules! キーワードと () => {} 構文に注目してください。これは入力パターンを持たないルールを定義しています。
この例を実行してみてください。
macro_rules! greet {
() => {
println!("Hello from a macro!");
};
}
fn main() {
greet!(); // Call our macro!
}デジグネーターで入力をキャプチャする
マクロは「デジグネーター」を使って入力を受け取れます。デジグネーターは、マクロがどの種類の Rust 構文をキャプチャするのかを指定します。
$expr:式(例:1 + 2、"hello")$ident:識別子(例:変数名、関数名)$ty:型(例:i32、String)$block:コードブロック(例:{ ... })- ほかにも多数あります。
引数を受け取るマクロ
ここでは、式($e:expr)を受け取り、その値を表示するマクロを示します。:expr がデジグネーターです。
キャプチャされた $e は、マクロの本体で使用できるようになります。stringify! マクロは、式をその文字列表現に変換します。
macro_rules! debug_print {
($e:expr) => {
println!("Debug: {} = {:?}", stringify!($e), $e);
};
}
fn main() {
let x = 10;
debug_print!(x + 5);
debug_print!("Rust macros are fun");
}複数の入力を処理する
同じ型の複数の引数をマクロに渡したい場合はどうすればよいでしょうか。繰り返し演算子 $()* を使用できます。
$():括弧内の内容が繰り返すパターンです。*:0回以上の繰り返しです。+:1回以上の繰り返しです。- 区切り文字も指定できます。たとえば、カンマ区切りの項目には
$(...),*を使用します。
繰り返し引数を持つマクロ
カンマで区切られた複数の式を受け取り、それぞれを個別に出力するマクロを作成してみましょう。これはリストのような構造を作成する場合に便利です。
macro_rules! print_all {
( $( $x:expr ),* ) => {
$( // This $(...)* repeats the `println!` call
println!("Item: {:?}", $x);
)*
};
}
fn main() {
print_all!(1, "hello", true, 3.14);
print_all!("Just one item");
}マクロの衛生性を理解する
Rustのマクロは「衛生的」です。これは、マクロの内部で定義された変数が、同じ名前であってもマクロの外部にある変数と意図せず衝突しないことを意味します。
コンパイラーは展開時に内部で名前を変更し、意図しない副作用を防ぎます。そのため、マクロをより安全で予測しやすく使用できます。
マクロをデバッグする方法
マクロが期待どおりに展開されないことがあります。Rustには、展開後のコードを確認する方法があります。
cargo expandを実行します(cargo-expandツールのインストールが必要です)。- ソースファイルに対して
rustc --pretty expandedを直接使用します。
これにより、マクロが生成する生のRustコードを確認できます。複雑なマクロの動作をデバッグして理解するうえで非常に役立ちます。
マクロのパターンマッチングクイズ
次のマクロ定義について考えてみましょう。
macro_rules! make_tuple {
( $x:expr, $y:expr ) => {
($x, $y)
};
}次のうち、正常にコンパイルされ、make_tuple! マクロを使用できる行はどれでしょうか。
振り返り:宣言的マクロ
このレッスンでは、macro_rules! を使用した宣言的マクロについて学びました。
- コンパイル時にコードを生成し、繰り返し現れるパターンを抽象化します。
- パターンマッチングを使用して、構文に基づいて入力を取り込みます。
$exprや$identなどの指定子で、想定する構文の種類を指定します。$()*などの繰り返し演算子で、柔軟な区切り文字を持つ複数の引数を処理します。- マクロは衛生的であり、意図しない名前の衝突を防ぎます。
マクロは、定型コードを減らし、柔軟で使いやすいRustのAPIを作成するための強力なツールです。
よくある質問
「宣言的マクロ(`macro_rules!`)」レッスンは無料ですか?
はい。「宣言的マクロ(`macro_rules!`)」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全3レッスンが含まれています。
「宣言的マクロ(`macro_rules!`)」で何を学びますか?
繰り返し現れるコードパターンを抽象化し、コンパイル時にコードを生成する宣言的マクロの書き方を学びます。 ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Learn Rust Codingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/3です。
「宣言的マクロ(`macro_rules!`)」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLearn Rust Codingレッスンでコードを書いて実行できますか?
はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 宣言的マクロ(`macro_rules!`)
- 手続き型マクロ:Derive、Function
- Unsafe Rustを扱う