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

nod*_*kai 5 macros metaprogramming hygiene rust

我认为“卫生”会防止X我的宏中定义的 s之间发生冲突m!,但事实并非如此。我有什么误解吗?

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

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

fn main() {
    m!(2);
    m!(3);
}
Run Code Online (Sandbox Code Playgroud)

操场

错误信息:

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

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

fn main() {
    m!(2);
    m!(3);
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*nov 3

来自Rust 编程语言(第一版)关于宏观卫生的部分

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

Rust 参考定义了items

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

项目完全在编译时确定,通常在执行期间保持固定,并且可以驻留在只读存储器中。

物品有以下几种:

  • 模块
  • extern crate声明
  • use声明
  • 函数定义
  • 类型定义
  • 结构体定义
  • 枚举定义
  • 联合定义
  • 常数项
  • 静态项目
  • 特质定义
  • 实施
  • extern

这是有道理的:如果您在宏中引入一个项目,您可能想从其他项目/模块/板条箱(因此在宏之外)实际使用它,但如果您不知道它的名称,则不能,所以编译器无法重命名它。