Macros 为什么宏卫生不能防止多个常量定义之间的冲突?

Macros 为什么宏卫生不能防止多个常量定义之间的冲突?,macros,rust,metaprogramming,hygiene,Macros,Rust,Metaprogramming,Hygiene,我以为“卫生”可以防止宏m中定义的Xs之间发生冲突但事实并非如此。我误解了什么 macro_rules! m { ($e:expr) => { const X: i32 = $e; }; } m!(0); m!(1); fn main() { m!(2); m!(3); } 错误消息: error[E0428]:名称“X”已定义多次 -->src/main.rs:3:9 | 3 |常数X:i32=$e; | ^^^^^

我以为“卫生”可以防止宏
m中定义的
X
s之间发生冲突但事实并非如此。我误解了什么

macro_rules! m {
    ($e:expr) => {
        const X: i32 = $e;
    };
}

m!(0);
m!(1);

fn main() {
    m!(2);
    m!(3);
}

错误消息:

error[E0428]:名称“X”已定义多次
-->src/main.rs:3:9
|
3 |常数X:i32=$e;
|         ^^^^^^^^^^^^^^^^^^
|         |
|`X`在这里重新定义
|在此之前对值“X”的定义
...
7米!(0);
|----在此宏调用中
|
=注意:`X`只能在此模块的值命名空间中定义一次
来自Rust编程语言(第一版)的:

此[即重命名]适用于
let
绑定和循环标签,但不适用于项

参考文件定义了:

物品是板条箱的组成部分。物品放在板条箱内 通过一组嵌套的模块。每个板条箱都有一个“最外层” 匿名模块;板条箱中的所有其他项目在 板条箱的模块树

项目在编译时完全确定,通常保持不变 在执行过程中,并且可以驻留在只读内存中

有几种项目:

  • 模块
  • 外部板条箱
    声明
  • 使用
    声明
  • 函数定义
  • 类型定义
  • 结构定义
  • 枚举定义
  • 联合定义
  • 固定项目
  • 静态项
  • 特征定义
  • 实现
  • extern
这很有意义:如果在宏中引入一个项,您可能希望实际使用其他项/模块/板条箱(因此在宏之外),但如果您不知道它的名称,则无法使用它,因此编译器无法重命名它。

谢谢。所以这是设计的。“如果你在宏中引入一个项目,你可能想实际使用它,”嗯,我想这不是我们应该如何使用宣传的卫生宏系统…@nodakai抱歉,我错过了“宏外”。在你的情况下,如果你把
println!(“X={}”,X)在最后一个
m!(3) 
,您希望它打印什么?当我听说Rust宏是卫生的时,我希望会出现“未知变量X”错误。这就是变量(
let
binding)所得到的结果,但是
const
没有引入。