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!();
相关推荐
羊小猪~~3 分钟前
前端入门一之BOM、window对象常见事件、定时器、JS执行机制、location对象、navigatior对象、history对象
开发语言·前端·javascript·css·vscode·html·visual studio
爱玛吧8 分钟前
手动实现promise的all,race,finally方法
开发语言·前端·javascript
C++ Learner18 分钟前
C语言中的 printf( ) 与 scanf( )
c语言·开发语言·数据结构·c++·人工智能
დ旧言~26 分钟前
【网络】传输层——UDP协议
服务器·开发语言·网络·网络协议·udp·php
政宇 | STAR30 分钟前
C++初级入门(1)
开发语言·c++·算法
java1234_小锋33 分钟前
java线程同步和异步有何异同,在什么情况下分别使用他们?
java·开发语言
bluebonnet271 小时前
【Rust练习】20.进一步深入特征
开发语言·算法·rust
苏三说技术1 小时前
明明表中没数据,竟然还能查出来?
后端
程序猿进阶1 小时前
Linux 文件权限
linux·运维·服务器·前端·数据库·后端·面试
孙同学_2 小时前
【C++】—掌握STL string类:string的模拟实现
java·开发语言·c++