你如何在自己的箱子里面使用宏?

Dou*_*oug 17 rust

我确信这是微不足道的,但我似乎无法使其发挥作用.

我看过http://doc.rust-lang.org/book/advanced-macros.html#scoping-and-macro-import/export,我很欣赏,一般来说,使用宏的方法是使用以下方法定义

#[macro_export]
macro_rules! background(($token:expr) => (($token >> (32 + 8)) & $crate::graphics::mask::Color));
Run Code Online (Sandbox Code Playgroud)

...然后将它们导入另一个使用它们的上下文:

#[macro_use]
extern crate terminal;
...
Run Code Online (Sandbox Code Playgroud)

但是,我想要做的是使用定义它们的包中的宏.

如果我的文件结构是:

- lib.rs
- macros.rs
- foo
- foo/mod.rs
- foo/junk.rs
Run Code Online (Sandbox Code Playgroud)

如何在junk.rs的macros.rs中使用宏?

我尝试过各种各样的组合#[macro_use] mod macros,没有运气.文档建议如果宏在某个范围内定义,那么它在所有子模块中都可用...这是否意味着我必须在lib.rs中定义我的宏?

Dou*_*oug 56

接受的答案是正确的,但对于将来发现此问题的其他人,我想补充一点,加载模块的顺序很重要.

例如,按此顺序:

pub mod terminal;
pub mod terminals;
pub mod graphics;

#[macro_use]
mod macros;
Run Code Online (Sandbox Code Playgroud)

如果终端使用宏中的宏,它将无法工作; 的#[macro_use]必须发生上述使用宏任何其他模块:

#[macro_use]
mod macros;

pub mod terminal;
pub mod terminals;
pub mod graphics;
Run Code Online (Sandbox Code Playgroud)

  • 这正是我的问题!我希望它在书中突出显示。 (2认同)

She*_*ter 18

您需要使用标记宏,#[macro_export]然后使用以下标记标记模块#[macro_use]:

#[macro_use]
mod macros {
    #[macro_export]
    macro_rules! my_macro(() => (42));
}

pub mod foo {
    pub mod junk {
        pub fn usage() -> u8 {
            my_macro!()
        }
    }
}

fn main() {
    println!("{:?}", foo::junk::usage());
}
Run Code Online (Sandbox Code Playgroud)

从技术上讲,#[macro_export]如果您希望宏可供您的箱子用户使用,则只需使用.

(游乐场链接)

  • 那是内联的,但是当我尝试使用文件时,它似乎没有;看看这个简单的例子 https://github.com/shadowmint/rust-starter;它错误为“src/module1/blah.rs:2:15:2:18 错误:宏未定义:'fmt!'”,但 https://raw.githubusercontent.com/shadowmint/rust-starter/master/src /lib.rs 正是你所说的。 (2认同)