我在同一个 crate 中的不同文件中有两个模块,其中 crate 启用了 macro_rules
。我想在另一个模块中使用一个模块中定义的宏。
// 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'
”...这是有道理的;宏系统在模块系统之前运行。我该如何解决这个问题?
最佳答案
同一个 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
,可以像其他任何项目一样使用和导入宏。并且与旧方法不同,这不依赖于源代码顺序,因此您可以在定义(源代码顺序)之前使用宏。
旧方法
bar!(); // Does not work! Relies on source code order!
#[macro_use]
mod foo {
macro_rules! bar {
() => ()
}
}
bar!(); // works
如果你想在同一个 crate 中使用宏,定义你的宏的模块需要属性 #[macro_use]
。请注意,宏只能在定义后使用!
跨 crate 的宏
Crate 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 2018 之前,您必须通过将属性 #[macro_use]
添加到 extern crate util;
语句来从其他 crate 导入宏。这将从 util
导入所有宏。不再需要此语法。
关于module - 如何跨模块文件使用宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51637870/