rust macro创建及使用

  • 创建一个rust macro
rust 复制代码
macro_rules! macro_name {
    ($元变量名:片段说明符) => {};  // 元变量名需要以$符号开头
    ()=>{}; // 可以定义多条规则
}
  • 当使用外部crate时,使用前缀(::)的完整路径,如use ::std::collections::HashSet;

  • 当使用当前的crate时,s使用(crate),如`use crate::mod1::fn1;`

  • 片段说明符(fragment specifiers)

    • 片段说明符确定的是元变量中允许使用那种数据
    • 可用的说明符
      • item
        *

        rust 复制代码
          // 可以存放任何项条目
          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
        *

        rust 复制代码
         // 块
         macro_rules! demo {
              ($b:block) => {
                  $b
              };
          }
          fn main() {
              let n = demo! {
                  {
                      if 1==1{true}else{false}
                  }
              };
              println!("{}", n);
          }
      • stmt
        *

        rust 复制代码
         // 需要一个语句
         macro_rules! demo {
              ($s:stmt) => {
                  $s
              };
          }
        
          fn main() {
              demo!(let name = "zhangsan");
              println!("{}",name);
          }
      • pat_param/pat
        *

        rust 复制代码
         // 模式pat(pattern)
         macro_rules! demo {
              ($p:pat) => {{
                  let n = 1;
                  match n {
                      1 => {
                          println!("1")
                      }
                      _ => {
                          println!("other num")
                      }
                  }
              }};
          }
        
          fn main() {
              demo!(2);
          }
      • expr
        *

        rust 复制代码
          // 表达式(expression)
          macro_rules! demo {
              ($e:expr) => {$e};
          }
        
          fn main() {
              demo!(2+2);
          }
      • ty
        *

        rust 复制代码
        // 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
        *

        rust 复制代码
        // 标识符(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
        *

        rust 复制代码
        // path路径
        macro_rules! demo {
              ($p:path) => {
                  use $p;
              };
          }
        
          fn main() {
              demo!(std::collections::HashSet);
          }
      • tt
        *

        rust 复制代码
        // token tree
        macro_rules! demo {
              ($t:tt) => {
                  $t {}
              };
          }
        
          fn main() {
              demo!(loop);
          }
      • meta
        *

        rust 复制代码
        // 可以用派生宏或类似宏
        macro_rules! demo {
              ($m:meta) => {
                  #[derive($m)]
                  struct Name;
              };
          }
        
          fn main() {
              demo!(Clone);
          }
      • lifetime
        *

        rust 复制代码
        // 为元变量提供生命周期
          macro_rules! demo {
              ($l:lifetime) => {
                  let name:&$l str = "zhangsan";
              };
          }
        
          fn main() {
              demo!('static);
          }
      • vis
        *

        rust 复制代码
        // 可见性(visibility)
        macro_rules! demo {
             ($v:vis) => {
                 $v struct Name;
             };
         }
        
         fn main() {
             demo!(pub);
         }
      • literal
        *

        rust 复制代码
        // 可以是一个数字或这是字符串
          macro_rules! demo {
              ($l:literal) => {
                  $l
              };
          }
        
          fn main() {
              demo!(1);
              demo!("zhangsna");
          }
  • 重复类型的宏

    • ? : 出现0或1次
    • +: 出现至少一次
    • * : 出现0或多次
    rust 复制代码
    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!();
相关推荐
uzong21 分钟前
我研读了 500 个 Spring Boot 生产级代码库,90% 都犯了这 7 个致命错误
后端
Legendary_0081 小时前
LDR6500:USB‑C DRP PD协议芯片技术详解与应用实践
c语言·开发语言
xiaobaoyu1 小时前
ssm知识点梳理
后端
2301_800976931 小时前
正则表达式
开发语言·python·正则表达式
故事还在继续吗1 小时前
C++20关键特性
开发语言·c++·c++20
IT_陈寒1 小时前
Vite的public文件夹放静态资源?这坑我替你踩了
前端·人工智能·后端
浮游本尊1 小时前
合同同步逻辑
后端
子兮曰2 小时前
别让爬虫白嫖你的导航站了:纯免费,手把手实现加密字体防爬
前端·javascript·后端
阿苟2 小时前
JAVA重点难点
后端