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 的语句

  1. 创建 log 项目

    cargo new log
  2. 在 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;
}
.
.
.
05-12 06:07