我认为“卫生”会阻止我的宏X
中定义的m!
之间的冲突,但结果并非如此。我误解了什么?
macro_rules! m {
($e:expr) => {
const X: i32 = $e;
}
}
m!(0);
m!(1);
fn main() {
m!(2);
m!(3);
}
错误讯息:
<anon>:3:9: 3:27 error: duplicate definition of value `X` [E0428]
<anon>:3 const X: i32 = $e;
^~~~~~~~~~~~~~~~~~
<anon>:8:1: 8:7 note: in this expansion of m! (defined in <anon>)
<anon>:3:9: 3:27 help: see the detailed explanation for E0428
<anon>:3:9: 3:27 note: first definition of value `X` here
<anon>:3 const X: i32 = $e;
^~~~~~~~~~~~~~~~~~
<anon>:7:1: 7:7 note: in this expansion of m! (defined in <anon>)
<anon>:3:9: 3:27 error: duplicate definition of value `X` [E0428]
<anon>:3 const X: i32 = $e;
...snip...
答案 0 :(得分:1)
来自https://doc.rust-lang.org/book/macros.html#hygiene:
这[即]重命名]适用于let绑定和循环标签,但不适用于项目
https://doc.rust-lang.org/reference.html#items:
项目是箱子的组成部分。项目由嵌套的模块组成。每个箱子都有一个最外面的#34;匿名模块;包中的所有其他项目都在包的模块树中有路径。
项目在编译时完全确定,通常在执行期间保持固定,并且可能驻留在只读存储器中。
有几种项目:
- extern crate declarations
- 使用声明
- 模块
- 功能
- 类型定义
- 结构
- 枚举
- 常量项
- 静态物品
- 性状
- 实现
这是有道理的:如果你在宏中介绍一个项目,你可能想要从其他项目/模块/板条箱中实际使用它(因此在宏外面),但是如果你没有&#39,你就不能这样做。 ; t知道它的名字,所以编译器不能重命名它。