在 Rust 各个模块文件中使用宏程序

Nilesh Katuwal 2023年1月30日 2022年7月18日
  1. Rust 宏
  2. Rust 中跨箱子的宏
  3. Rust 中同一个 Crate 中的宏
在 Rust 各个模块文件中使用宏程序

在本文中,我们将学习如何在 Rust 中跨模块文件使用宏。

Rust 宏

Rust 提供了很好的宏支持。例如,通过宏启用的元编程涉及编写编写其他代码的代码。

提供与函数相当的能力,但没有相关的运行时成本。由于在编译时扩展,因此构建时间成本是相关的。

Rust 宏与 C 宏有很大不同。例如,Rust 宏应用于标记树,而 C 宏替换文本。

语法:

*MacroRulesDefinition* :
  `macro_rules` `!` [IDENTIFIER] *MacroRulesDef*
MacroRules :
   MacroRule ( ; MacroRule )* ;?

MacroRule :
   MacroMatcher => MacroTranscriber

Rust 中跨箱子的宏

crate 包括模块范围的层次结构。crate 中的任何对象都有一个规范的模块路径,指示其在模块树中的位置。

在这个树的顶层,有一个匿名模块。Rust 源文件指定了一个模块,其名称和在当前 crate 的模块树中的位置是外部定义的:或者通过引用源文件中的显式 Module 项。

它也可能是板条箱本身的名称。每个源文件都是一个模块。

然而,并不是每个模块都需要它的源文件:模块定义可以在单个源文件中分层。

板条箱 util

#[macro_export]
macro_rules! foo {
    () => ()
}

板条箱用户

use util::foo;

foo!();

请注意,使用此策略时,宏始终位于 crate 的顶层。即使 foo 包含在 mod bar 中,user crate 仍然必须写 use util::foo; 而不是使用 util::bar::foo;

你可以使用 pub use 从 crate 的模块中导出宏。

Rust 中同一个 Crate 中的宏

foo::bar!();

mod foo {
    macro_rules! bar {
        () => ()
    }

    pub(crate) use bar;
}

foo::bar!();

宏可以通过 pub use 导入并用作任何其他对象。与旧方法不同,这不依赖于源代码顺序,因此你可以在宏编写之前使用它。

每个都有一个名称和一个或多个规则。每个规则由两部分组成:一个匹配器,它描述它匹配的语法,一个转录器,它描述将被成功匹配的调用替换的语法。

分隔符必须包含匹配器和转录器。表达式、语句、特征、实现、外来项、类型和模式可以通过宏进行扩展。