マクロの定義側と利用側で識別子を共有する方法について。

基礎知識

マクロの定義側と利用側では、識別子のための空間が異なる。

これにより、定義側も利用側も識別子の衝突を気にせずにコーディングできる。

逆に、識別子を共有したい場合、識別子の名前をキャプチャ ($ に続く識別子) で導入する。

失敗例

以下では、マクロ with_var_x の定義側と利用側で識別子 x を共有していない。


macro_rules! with_var {
    ($block:block) => {
        let x = "hello";
        $block
    }
}

fn main() {
    with_var!({ println!("{x}") });
}

error[E0425]: cannot find value `x` in this scope
 --> src/main.rs:9:28
  |
9 |     with_var!({ println!("{x}") });
  |                            ^ not found in this scope

解決策

以下では、マクロ with_var の定義側と利用側で識別子 x を共有している。


macro_rules! with_var {
    ($var:ident $block:block) => {
        let $var = "hello";
        $block
    }
}

fn main() {
    with_var!(x { println!("{x}") });
}