宏可以匹配常量参数而不是文字吗?

ide*_*n42 2 macros rust

鉴于宏匹配示例,这显示了宏如何匹配参数。

我在这里做了非常小的改动来使用数字:

macro_rules! foo {
    (0 => $e:expr) => (println!("mode X: {}", $e));
    (1 => $e:expr) => (println!("mode Y: {}", $e));
}

fn main() {
    foo!(1 => 3);
}
Run Code Online (Sandbox Code Playgroud)

作品、印刷: mode Y: 3

但是我想使用一个常量作为参数,这可以起作用吗:

const CONST: usize = 1;

macro_rules! foo {
    (0 => $e:expr) => (println!("mode X: {}", $e));
    (1 => $e:expr) => (println!("mode Y: {}", $e));
}

fn main() {
    foo!(CONST => 3);
}
Run Code Online (Sandbox Code Playgroud)

这在 Rust 中可能吗?


请注意,使用常规match语句对我来说不可用,因为在我的代码中,每个分支都解析为不同的类型,从而产生错误。所以我特别想知道是否可以将常量传递给宏。

Mat*_* M. 6

不。

宏在抽象语法树上运行,因此它们在句法级别进行推理:它们对标记及其拼写进行推理。

例如:

fn main() {
    let v = 3;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,AST 将类似于:

fn main
    \_ let-binding v
        \_ literal 3
Run Code Online (Sandbox Code Playgroud)

如果您询问宏是否v3,它会看着您很有趣,并想知道您为什么要尝试比较变量名称和文字。

  • 我认为这不是*完全* AST - 宏被赋予了未完全解析的标记(因为,当然,宏部分定义了如何解析它们)。我说未完全解析而不是未解析,因为您确实有 `$e:expr`。 (2认同)