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!();
相关推荐
阿维的博客日记16 小时前
spring里面的@RequestParam什么意思
java·后端·spring
影寂ldy16 小时前
C# 五大加密算法全套实战(AES/DES对称、RSA非对称、MD5/SHA256哈希)
开发语言·c#·哈希算法
金金金__16 小时前
腾讯云COS接入配置
后端
Hyyy16 小时前
Git Worktree 完全讲解
前端·后端·面试
罗超驿17 小时前
6.Java LinkedList深度解析:从链表原理到源码实践
java·开发语言·链表
2501_9481069117 小时前
计算机毕业设计之jsp物业管理系统
java·大数据·开发语言·汽车·课程设计
独孤留白17 小时前
从C到Rust:Mutex / RwLock / Atomic 跨线程局部可变性
rust
逝水无殇17 小时前
C# 反射详解
开发语言·后端·c#
Cache技术分享17 小时前
465. Java 反射 - 获取类的简单名
前端·后端
做系统的大强17 小时前
REPL里的HLT:main_stmts为空时的致命尾声
后端