Macros 宏是否可以匹配常量参数而不是文本?

Macros 宏是否可以匹配常量参数而不是文本?,macros,rust,Macros,Rust,给定参数,这将显示宏如何匹配参数 我在这里对数字做了非常小的更改: macro_rules! foo { (0 => $e:expr) => (println!("mode X: {}", $e)); (1 => $e:expr) => (println!("mode Y: {}", $e)); } fn main() { foo!(1 => 3); } 作品,印刷:模式Y:3 然而,我想使用一个常数作为参数,这是否可行: const C

给定参数,这将显示宏如何匹配参数

我在这里对数字做了非常小的更改:

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

fn main() {
    foo!(1 => 3);
}
作品,印刷:模式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);
}
这在铁锈中可能吗

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

我很确定答案是否定的;在宏扩展时,您只有标记树—扩展发生在求值之前,甚至是类型推断/检查之前。

我相当肯定答案是否定的;在宏扩展时,您所拥有的只是令牌树—扩展发生在求值之前,甚至在类型推断/检查之前。

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

例如:

fn main() {
    let v = 3;
}
在这种情况下,AST将类似于:

fn main
    \_ let-binding v
        \_ literal 3
如果你问一个宏v是否为3,它会觉得你很有趣,并且想知道为什么你会尝试比较变量名和文本。

const CONST: usize = 0;

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

fn main() {
    foo!(CONST => 3);
}
宏操作抽象语法树,因此它们在语法级别进行推理:它们对标记及其拼写进行推理

例如:

fn main() {
    let v = 3;
}
在这种情况下,AST将类似于:

fn main
    \_ let-binding v
        \_ literal 3
如果你问一个宏v是否为3,它会觉得你很有趣,并且想知道为什么你会尝试比较变量名和文本

const CONST: usize = 0;

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

fn main() {
    foo!(CONST => 3);
}
若要在宏中使用标识符,它需要是ident标记,并且可以使用If、else-If块而不是match


如果您想在宏中使用标识符,它需要是ident标记,您可以使用If、else-If块而不是match。

我认为这并不完全是AST-宏没有得到完全解析的标记,因为宏部分定义了如何解析它们。我说的是未完全解析,而不是未解析,因为您确实有$e:expr。@ChrisEmerson:是的,它比这个要宽松一些。我认为这并不完全是AST-宏被赋予了未完全解析的标记,因为,当然,宏部分地定义了如何解析它们。我说的是未完全解析,而不是未解析,因为您有$e:expr。@ChrisEmerson:是的,它比这个要宽松一些。您说每个分支解析为不同的类型。你能举个例子吗?你说每个分支解析为不同的类型。你能举个例子吗?请不要只发布代码作为答案,还要解释你的代码的作用以及它是如何解决问题的。带有解释的答案通常更有帮助,质量更好,并且更有可能吸引更多的选票。感谢您的警告。请不要仅将代码作为答案发布,还要解释代码的作用以及它如何解决问题。带解释的答案通常更有帮助,质量更好,更容易吸引选票。谢谢你的警告。