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
}
posted @ 2023-05-05 01:23  小土坡  阅读(291)  评论(0)    收藏  举报