rust 如何在同一机箱中导入/使用不同模块的宏?

wj8zmpe1  于 2022-11-30  发布在  其他
关注(0)|答案(1)|浏览(271)
真实的生活场景:

我想在crate::app::args::parse模块中使用crate::app::verbose_trace!("string literal")

可重现场景:

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

#[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!();
  }

编译器抱怨

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`

就像完全失明一样:0

我读:
我希望看到:
  • 我的示例的可编译版本。
  • 解释为什么它没有编译失败。
  • 可选:
  • 关于如何在子模块/超模块中使用宏的一些其他建议。
hts6caw3

hts6caw31#

#[macro_export]将宏导出到crate根下。因此,crate::baz!()可以工作,但foo::baz!()不行(您不需要#[macro_use],它是为了在另一个crates中使用宏)。
如果要导出 * 此路径 * 中的宏,对于crate本地宏,请不要使用#[macro_export]作为all。相反,导出如下所示的宏:

macro_rules! baz {
    () => {
        println!("baz works")
    };
}
pub(crate) use baz;

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

#[macro_export]
macro_rules! baz {
    () => {
        println!("baz works")
    };
}
pub use baz;

这将同时在crate根目录和foo目录下导出宏。

相关问题