Rust 1.7.0 macro宏的复用 #[macro_use]的用法
Rust 1.7.0 中的宏使用范围包括三种情况: 第一种情况是宏定义在当前文件中,这个文件可能是 crate 默认的 module,也可能是任意的 module 模块。 第二种情况是宏定义在当前 crate ,但是不是在当前文件中,而是其他 module 模块中。 第三种情况是宏定义在其他的 crate 中,或者其他的 crate 子模块中。
使用#[macro_use] 可以使被注解的module模块中的宏应用到当前作用域中;或者注释crate中的宏应用到当前crate作用域中。
第一种情况的例子:
macro_rules! say_hello{ ()=>( println!("Hello"); ) } fn main(){ say_hello!(); }
第二种情况:
-
先创建一个新文件 macros.rs ,定义一个宏 say_bonjour
macro_rules! say_bonjour{ ()=>( println!("Bonjour"); ) }
-
使用
#[macro_use] pub mod macros; macro_rules! say_hello{ ()=>( println!("Hello"); ) } fn main(){ say_hello!(); say_bonjour!(); }
-
如果没有 #[macro_use] 编译会出现 error: macro undefined: ‘say_bonjour!’
第三种情况:注释在外部 crate 的语句
- 创建 log 项目 cargo new log
- 在 log 项目中,lib.rs 是入口,在lib.rs中定义 macors 模块。
. . . #[macro_use] mod macros; . . .
然后,创建对应mod macros 的 macros.rs 文件 vi src/macros.rs 声明宏 log、error、warn、info,在每个宏定义前面添加 #[macro_export]注释,表示这些宏可以被外部的 crate 使用。
. . . #[macro_export] macro_rules! log { ... } #[macro_export] macro_rules! error { (target: $target:expr, $($arg:tt)*) => ( log!(target: $target, $crate::LogLevel::Error, $($arg)*); ); ($($arg:tt)*) => ( log!($crate::LogLevel::Error, $($arg)*); ) } #[macro_export] macro_rules! warn { (target: $target:expr, $($arg:tt)*) => ( log!(target: $target, $crate::LogLevel::Warn, $($arg)*); ); ($($arg:tt)*) => ( log!($crate::LogLevel::Warn, $($arg)*); ) } #[macro_export] macro_rules! info { (target: $target:expr, $($arg:tt)*) => ( log!(target: $target, $crate::LogLevel::Info, $($arg)*); ); ($($arg:tt)*) => ( log!($crate::LogLevel::Info, $($arg)*); ) } . . .
使用:引入 log crate的时候,注明#[macro_use]
#[macro_use] extern crate log; . . . if !shutdown.load(Ordering::SeqCst) { info!("ConnectionHandler: read timed out ({:?}). Server not shutdown, so retrying read.", err); continue; } else { info!("ConnectionHandler: read timed out ({:?}). Server shutdown, so closing connection.", err); break; } . . .