Как вы используете макрос внутри своего ящика?
Я уверен, что это тривиально, но я не могу заставить его работать.
Я просмотрел 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));
... и затем импортировать их в другой контекст, который использует их, используя:
#[macro_use]
extern crate terminal;
...
Однако я хочу, чтобы использовать макросы из ящика, где они определены.
Если моя файловая структура:
- lib.rs
- macros.rs
- foo
- foo/mod.rs
- foo/junk.rs
Как использовать макросы в macros.rs из junk.rs?
Я пробовал различные комбинации #[macro_use] mod macros
и т.д. без везения. Документация предполагает, что если макрос определен в некоторой области, то он доступен во всех дочерних модулях... означает ли это, что я должен определить свои макросы в lib.rs?
Ответы
Ответ 1
Вам нужно отметить свой макрос #[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());
}
Технически вам нужно использовать #[macro_export]
, если вы хотите, чтобы макрос был доступен для пользователей вашего ящика.
(ссылка для воспроизведения)
Ответ 2
Принятый ответ правильный, но для любого, кто найдет этот вопрос в будущем, я хотел бы добавить, что порядок загрузки модулей важен.
Например, в этой последовательности:
pub mod terminal;
pub mod terminals;
pub mod graphics;
#[macro_use]
mod macros;
Если терминал использует макрос из макросов, он не будет работать; #[macro_use]
должен происходить над любым другим модулем, который использует макрос:
#[macro_use]
mod macros;
pub mod terminal;
pub mod terminals;
pub mod graphics;