rust macro创建及使用

  • 创建一个rust macro
macro_rules! macro_name {
    ($元变量名:片段说明符) => {};  // 元变量名需要以$符号开头
    ()=>{}; // 可以定义多条规则
}
  • 当使用外部crate时,使用前缀(::)的完整路径,如use ::std::collections::HashSet;
  • 当使用当前的crate时,s使用($crate),如use $crate::mod1::fn1;
  • 片段说明符(fragment specifiers)
    • 片段说明符确定的是元变量中允许使用那种数据
    • 可用的说明符
      • item
        •   // 可以存放任何项条目
            macro_rules! demo {
                ($i:item) => {
                    $i
                };
            }
          
            fn main() {
                demo!(
                    fn add(a: i32, b: i32) -> i32 {
                        a + b
                    }
                );
                println!("{}", add(1, 2));
                demo!(
                    const A: &str = "demo";
                );
                println!("{}", A);
                demo!(
                    mod mod_name {}
                );
            }
          
      • block
        •  // 块
           macro_rules! demo {
                ($b:block) => {
                    $b
                };
            }
            fn main() {
                let n = demo! {
                    {
                        if 1==1{true}else{false}
                    }
                };
                println!("{}", n);
            }
          
      • stmt
        •  // 需要一个语句
           macro_rules! demo {
                ($s:stmt) => {
                    $s
                };
            }
          
            fn main() {
                demo!(let name = "zhangsan");
                println!("{}",name);
            }
          
      • pat_param/pat
        •  // 模式pat(pattern)
           macro_rules! demo {
                ($p:pat) => {{
                    let n = 1;
                    match n {
                        1 => {
                            println!("1")
                        }
                        _ => {
                            println!("other num")
                        }
                    }
                }};
            }
          
            fn main() {
                demo!(2);
            }
          
      • expr
        •   // 表达式(expression)
            macro_rules! demo {
                ($e:expr) => {$e};
            }
          
            fn main() {
                demo!(2+2);
            }
          
      • ty
        • // ty(type)类型
          macro_rules! demo {
                ($t:ty) => {
                    fn add(r: $t, l: $t) -> $t {
                        r + l
                    }
                    println!("{}", add(1, 2));
                };
            }
          
            fn main() {
                demo!(i32);
            }
          
      • ident
        • // 标识符(identifier)
          macro_rules! demo {
                ($i:ident,$ii:ident) => {
                    fn $i() {
                        println!("1");
                    }
                    let $ii = 5;
                };
            }
          
            fn main() {
                demo!(num, five);
                assert_eq!(5, five);
                num();
            }
          
      • path
        • // path路径
          macro_rules! demo {
                ($p:path) => {
                    use $p;
                };
            }
          
            fn main() {
                demo!(std::collections::HashSet);
            }
          
      • tt
        • // token tree
          macro_rules! demo {
                ($t:tt) => {
                    $t {}
                };
            }
          
            fn main() {
                demo!(loop);
            }
          
      • meta
        • // 可以用派生宏或类似宏
          macro_rules! demo {
                ($m:meta) => {
                    #[derive($m)]
                    struct Name;
                };
            }
          
            fn main() {
                demo!(Clone);
            }
          
      • lifetime
        • // 为元变量提供生命周期
            macro_rules! demo {
                ($l:lifetime) => {
                    let name:&$l str = "zhangsan";
                };
            }
          
            fn main() {
                demo!('static);
            }
          
      • vis
        • // 可见性(visibility)
          macro_rules! demo {
               ($v:vis) => {
                   $v struct Name;
               };
           }
          
           fn main() {
               demo!(pub);
           }
          
      • literal
        • // 可以是一个数字或这是字符串
            macro_rules! demo {
                ($l:literal) => {
                    $l
                };
            }
          
            fn main() {
                demo!(1);
                demo!("zhangsna");
            }
          
  • 重复类型的宏
    • ? : 出现0或1次
    • +: 出现至少一次
    • * : 出现0或多次
    • macro_rules! demo {
        ($($metavar:frag),*) => {
            $($metavar)*
        }
      }
      
      // 0或1次
      macro_rules! num {
        (
            $($l:literal)?
        ) => {
            $($l)?
        }
      }
      num!();
      num!(0);
      
      // 至少1次
      macro_rules! num {
        (
            $($l:literal),+
        ) => {
            $($l;)+
        }
      }
      num!(1,2,3);
      num!(0);
      
      // 0或多次
      macro_rules! num {
        (
            $($l:literal),*
        ) => {
            $($l;)*
        }
      }
      num!(1,2,3);
      num!(0);
      num!();
      
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值