Rust 宏可以跨版本共享吗?

Viv*_*dav 4 macros rust rust-macros rust-2018 rust-2021

假设 Rust 2018 宏async在其中定义了一个函数。它使用的语法与 Rust 2015 不兼容。因此,如果您使用 2015 版本编译您的包,宏中的扩展代码不会与之冲突吗?

我不太熟悉过程宏或声明性宏的内部工作原理,但我想它们需要生成特定于版本的代码,因为它们的输出将被视为与其余代码相同。如果是这样,我如何跨版本边界共享宏导出。我需要根据每个版本重新编写它们吗?这似乎无法扩展,特别是如果版本应该每 3 年左右发布一次。

E_n*_*ate 11

是的,在一个版本下开发的宏可以由其他版本中的代码使用。

这是经过精心策划的,作为版本机制的一部分,以防止生态系统停滞。特别是对于宏,Rust 版本指南对此进行了更详细的解释:

宏使用称为“版本卫生”的系统,其中宏中的标记标有它们来自哪个版本。这允许从不同版本的包中调用外部宏,而无需担心它是从哪个版本调用的。

给出了仅适用于 2015 版的宏示例:

#[macro_export]
macro_rules! foo {
    () => {
        let dyn = 1;
        println!("it is {}", dyn);
    };
}
Run Code Online (Sandbox Code Playgroud)

它用作dyn标识符,这在 Rust 2018 中是非法的。但是,由于该宏是在 2015 版中编写的,因此在此上下文中编写的任何代码都会根据该版本的规则进行解析和解释,与调用者的代码隔离。由于宏的这种“卫生性”,它们可以在 Rust 2018、2021 或任何其他版本中无缝使用。

同样的情况也适用于最新版本中编写的宏。即使过程宏声明了一个async函数,最终还是有一个不依赖于该语法的共同点(MIR)。

当然,唯一的例外是在版本之间迁移现有代码时。