为什么宏卫生不能阻止多个const定义之间的冲突? [英] Why does macro hygiene not prevent collisions between multiple const definitions?

查看:114
本文介绍了为什么宏卫生不能阻止多个const定义之间的冲突?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为卫生"可以防止在宏m!中定义的X之间发生冲突,但事实并非如此.我有什么误会?

I thought "hygiene" would prevent collisions between Xs defined within my macro m! but that turned out not to be the case. What am I misunderstanding?

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

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

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

游乐场

错误消息:

error[E0428]: the name `X` is defined multiple times
 --> src/main.rs:3:9
  |
3 |         const X: i32 = $e;
  |         ^^^^^^^^^^^^^^^^^^
  |         |
  |         `X` redefined here
  |         previous definition of the value `X` here
...
7 | m!(0);
  | ------ in this macro invocation
  |
  = note: `X` must be defined only once in the value namespace of this module

推荐答案

来自 Rust编程语言(第一版)的

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

This [i.e. renaming] holds for let bindings and loop labels, but not for items

Rust参考定义了项目:

The Rust reference defines items:

一个物品是一个箱子的组成部分.物品放在箱子里组织 由一组嵌套的模块组成.每个板条箱都只有一个最外侧" 匿名模块;箱子中所有其他物品的路径都在 板条箱的模块树.

An item is a component of a crate. Items are organized within a crate by a nested set of modules. Every crate has a single "outermost" anonymous module; all further items within the crate have paths within the module tree of the crate.

项目完全在编译时确定,通常保持固定 在执行过程中,可能驻留在只读存储器中.

Items are entirely determined at compile-time, generally remain fixed during execution, and may reside in read-only memory.

有几种项目:

  • 模块
  • extern crate声明
  • use声明
  • 功能定义
  • 类型定义
  • 结构定义
  • 枚举定义
  • 联盟定义
  • 常数项
  • 静态物品
  • 特征定义
  • 实现
  • extern
  • modules
  • extern crate declarations
  • use declarations
  • function definitions
  • type definitions
  • struct definitions
  • enumeration definitions
  • union definitions
  • constant items
  • static items
  • trait definitions
  • implementations
  • extern blocks

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

This makes sense: if you you introduce an item in a macro you presumably want to actually use it from other items/modules/crates (and thus outside the macro), but you can't if you don't know its name, so the compiler can't rename it.

这篇关于为什么宏卫生不能阻止多个const定义之间的冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆