在Rust中,如何跨板条箱中的文件导入分层宏?

pinkon5k  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(180)

我有宏调用另一个宏。这是文件的简化版本(实际的外部宏有匹配的逻辑)。

macro_rules! outer_macro {
    () => (
        inner_macro!()
    )
}

macro_rules! inner_macro{
    () => (
        // stuff
    )
}

当我把这些宏放在调用outer_macro的同一个文件(src/caller.rs)中时,一切都正常,但我把它们移到了它们自己的文件src/macros.rs中,现在src/caller.rs找不到outer_macro了。
我试着在outer_macropub mod macros;上添加#[macro_export]src/lib.rs,现在src/caller.rs可以找到outer_macro,但是outer_macro找不到inner_macro

#[macro_export]
macro_rules! outer_macro {
    () => (
        inner_macro!()
        ^^^^^^^^^^^
    )
}

macro_rules! inner_macro{
    () => (
        // stuff
    )
}

如何使outer_macro可用于机箱的其余部分,同时将inner_macro保持在其范围内?

hgqdbh6s

hgqdbh6s1#

这里的问题是宏实际上没有引用inner_macro;相反,它只是简单地将字符串inner_macro!()复制粘贴到使用宏的任何地方,因此,inner_macro在任何地方都必须是有效路径;换句话说,使用outer_macro内部的绝对路径:

  • 源代码/macros.rs*:
macro_rules! outer_macro {
    () => {
        crate::macros::inner_macro!()
    };
}

macro_rules! inner_macro {
    () => {
        // stuff
    };
}

pub(crate) use inner_macro;
pub(crate) use outer_macro;
  • 源代码/main.rs*:
mod macros;

fn main() {
    macros::outer_macro!();
}

“如何使outer_macro可用于机箱的其余部分,同时将inner_macro保持在其范围内?”
你不能,这就是宏的意义:它们实际上用新代码替换了宏调用,这意味着插入的新代码必须对调用位置也有效,也就是说,如果你在outer_macro中使用inner_macro调用,那么在使用outer_macro的任何地方都必须可见。
另一种选择是使用internal rules,正如@Jmb指出的那样:

macro_rules! outer_macro {
    () => {
        crate::macros::outer_macro!(@inner_macro)
    };
    (@inner_macro) => {
        // stuff
    }
}

pub(crate) use outer_macro;

这实际上会隐藏内部宏。

相关问题