我应该如何为自定义模块使用 `macro_export`

How should I use `macro_export` for a custom module

我有以下结构:

里面 queues.rs 我有一个 #[macro_export],

#[macro_export]
macro_rules! queue {...}

但我不确定如何在 lib.rs 中导入它。

我得到的是这样的:

use crate::utils::queues::*;

// use it here
let mut service_queue: Queue<isize> = queue![];

这会引发错误

error: cannot find macro `queue` in this scope
  --> src/broker.rs:54:51
   |
54 |             let mut service_queue: Queue<isize> = queue![];
   |                                                   ^^^^^
   |
   = note: consider importing this macro:
           crate::queue
   = help: have you added the `#[macro_use]` on the module/import?

在此处键入 #[macro_use] 并从 utils 导入我的自定义宏的正确方法是什么?

您可以使用 lib.rs 中的 queue! 宏使用 #[macro_use] attribute (playground):

#[macro_use]
mod utils {
    #[macro_use]
    mod queues {
        macro_rules! queue {
            () => { vec![] };
        }
    }
}

pub fn foo() {
    let _service_queue: Vec<isize> = queue![];
}

在您现有的代码中,您使用的是 #[macro_export],这意味着它是 declared in the crate root scope 而不是 utils::queues 模块。在您的错误消息中,您可以看到编译建议 consider importing this macro: crate::queue.

在这种情况下访问它 (playground):

mod utils {
    mod queues {
        #[macro_export]
        macro_rules! queue {
            () => { vec![] };
        }
    }
}

pub fn foo() {
    let _service_queue: Vec<isize> = queue![];
}

请注意,在任何一种情况下,use crate::utils::queues::*; 语句都没有帮助,实际上您会收到 unused_imports 警告(除非您碰巧在该模块中声明了其他项目)。

还有this trick (playground):

pub mod utils {
    pub mod queues {
        macro_rules! queue {
            () => { vec![] };
        }
        pub(crate) use queue;
    }
}

pub fn foo() {
    let _service_queue: Vec<isize> = crate::utils::queues::queue![];
}

旁白:如果您打算在其他 crate 中使用宏并且希望保留模块层次结构(即从 my_crate::utils::queues::queue!my_other_crate 访问),则有一种(复杂的)方法可以做到那。