Rust 中的 macro_rules! 声明宏
像 Rust 中的 println!()这样以 ! 结尾的函数就是声明宏,定义方式使用 macro_rules! 。
一个简单的例子
该例子这个宏没有参数,调用方法:cutting_line!();
#[macro_export]
macro_rules! cutting_line {
() => {
println!("-------------------------------------");
}
}
宏参数类型
| block | expr(表达式) | ident(函数名/变量名) | item 程序项 | lifetime |
|---|---|---|---|---|
| literal | meta | pat (模式 pattern) | path | stmt (语句 statement) |
| tt (标记树 token tree) | ty (类型 type) | vis |
重复运算符
*— 表示任意数量的重复元。+— 表示至少有一个重复元。?— 表示一个可选的匹配段,可以出现零次或一次。
ident 参数例子
这里用到了一个字符串化宏 stringify!($func_name),ident 可以是变量名或函数名。
#[macro_export]
macro_rules! create_fn {
($func_name: ident) => {
fn $func_name() {
println!("{} output!", stringify!($func_name));
}
};
}
xtp_lib::create_fn!(func); // 创建一个函数 func
func();
expr 表达式例子
#[macro_export]
macro_rules! print_result {
($expression: expr) => {
println!("{:?} = {:?}", stringify!($expression), $expression);
};
}
xtp_lib::print_result!(1u32+1);
xtp_lib::print_result!({
let x = 12;
x + 10 -2
});
输出:
"1u32 + 1" = 2
"{ let x = 12; x + 10 - 2 }" = 20
参数重载
#[macro_export]
macro_rules! test {
($left: expr; and $right: expr) => {
println!("{:?} and {:?} is {:?}",
stringify!($left),
stringify!($right),
$left && $right
);
};
($left: expr; or $right: expr) => {
println!("{:?} or {:?} is {:?}",
stringify!($left),
stringify!($right),
$left || $right
);
};
}
输出:
"1 + 1 == 2" and "2 + 2 == 4" is true
"1 + 1 == 2" or "2 + 2 == 5" is true
重载
宏在参数列表中可以使用
+来表示一个参数可能出现一次或多次,使用*来表示该参数可能出现零次或多次。
#[macro_export]
macro_rules! find_min {
($x: expr) => ($x);
($x: expr, $($y: expr), +) => {
std::cmp::min($x, find_min!($($y), +))
};
}
fn main() {
println!("{}", find_min(20, 30, 100, 2)); // 输出:2
}

浙公网安备 33010602011771号