如何跨模块文件使用宏? [英] How do I use a macro across module files?

查看:18
本文介绍了如何跨模块文件使用宏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在同一个 crate 中的单独文件中有两个模块,其中 crate 启用了 macro_rules.我想在另一个模块中使用一个模块中定义的宏.

I have two modules in separate files within the same crate, where the crate has macro_rules enabled. I want to use the macros defined in one module in another module.

// macros.rs
#[macro_export] // or not? is ineffectual for this, afaik
macro_rules! my_macro(...)

// something.rs
use macros;
// use macros::my_macro; <-- unresolved import (for obvious reasons)
my_macro!() // <-- how?

我目前遇到编译器错误macro undefined: 'my_macro'"...这是有道理的;宏系统先于模块系统运行.我该如何解决这个问题?

I currently hit the compiler error "macro undefined: 'my_macro'"... which makes sense; the macro system runs before the module system. How do I work around that?

推荐答案

同一个 crate 中的宏

新方法(自 Rust 1.32,2019-01-17 起)

foo::bar!();  // works

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

    pub(crate) use bar;    // <-- the trick
}

foo::bar!();  // works

通过pub use,可以像任何其他项目一样使用和导入宏.与旧方法不同的是,这不依赖于源代码顺序,因此您可以在定义(源代码顺序)之前使用宏.

With the pub use, the macro can be used and imported like any other item. And unlike the older method, this does not rely on source code order, so you can use the macro before (source code order) it has been defined.

bar!();   // Does not work! Relies on source code order!

#[macro_use]
mod foo {
    macro_rules! bar {
        () => ()
    }
}

bar!();    // works

如果你想在同一个 crate 中使用宏,定义你的宏的模块需要属性 #[macro_use].请注意,宏只能在定义后使用!

If you want to use the macro in the same crate, the module your macro is defined in needs the attribute #[macro_use]. Note that macros can only be used after they have been defined!

Crate util

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

Crate user

use util::foo;

foo!();

请注意,使用此方法,宏始终位于 crate 的顶层!因此,即使 foo 位于 mod bar {} 内,user 箱子仍然必须编写 use util::foo;not 使用 util::bar::foo;.通过使用 pub use,您可以从 crate 的模块中导出宏(除了在根中导出之外).

Note that with this method, macros always live at the top-level of a crate! So even if foo would be inside a mod bar {}, the user crate would still have to write use util::foo; and not use util::bar::foo;. By using pub use, you can export a macro from a module of your crate (in addition to it being exported at the root).

在 Rust 2018 之前,您必须通过将属性 #[macro_use] 添加到 extern crate util; 语句来从其他 crate 导入宏.这将从 util 导入所有宏.不再需要此语法.

Before Rust 2018, you had to import macro from other crates by adding the attribute #[macro_use] to the extern crate util; statement. That would import all macros from util. This syntax should not be necessary anymore.

这篇关于如何跨模块文件使用宏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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