如何从同一个板条箱中的不同模块导入/使用宏?

Sii*_*iir 6 import macros visibility export rust

现实生活场景:

我想使用crate::app::verbose_trace!("string literal")内部crate::app::args::parse模块。

可重现的场景:

经过一个小时的尝试,我得到了以下简单的例子。它暴露了我对宏的误解。

  #[macro_use]
  mod foo{
      pub fn bar(){
          println!("bar works")
      }
      #[macro_export]
      macro_rules! baz{
          ()=> {println!("baz works")}
      }
  }

  fn main(){
      foo::bar();
      foo::baz!();
      // Following doesn't work either:
      // use foo::baz;
      // baz!();
  }
Run Code Online (Sandbox Code Playgroud)

编译器抱怨

  error[E0433]: failed to resolve: could not find `baz` in `foo`
  --> src\main.rs:14:14
  |
  14 |         foo::baz!();
  |              ^^^ could not find `baz` in `foo`
Run Code Online (Sandbox Code Playgroud)

就好像它完全盲目一样:0

我读:
我想看看:
  • 我的示例的可编译版本。
  • 解释为什么它无法编译。
  • 可选:
    • 关于如何在子模块/超级模块中使用 marco 的一些其他建议。

Cha*_*man 11

#[macro_export]将宏导出到 crate root 下。因此,crate::baz!()可以工作,但foo::baz!()不会(并且您不需要#[macro_use],它是为了在另一个板条箱中使用宏)。

如果你想导出这个路径中的宏,对于 crate 本地宏不要#[macro_export]全部使用。相反,导出宏,如下所示:

macro_rules! baz {
    () => {
        println!("baz works")
    };
}
pub(crate) use baz;
Run Code Online (Sandbox Code Playgroud)

要导出宏以在其他板条箱中使用,您仍然需要#[macro_export]

#[macro_export]
macro_rules! baz {
    () => {
        println!("baz works")
    };
}
pub use baz;
Run Code Online (Sandbox Code Playgroud)

这将在 crate root 和foo.