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!();
相关推荐
Sylvia-girl2 小时前
Java——抽象类
java·开发语言
Yana.nice4 小时前
Bash函数详解
开发语言·chrome·bash
FreeBuf_5 小时前
黄金旋律IAB组织利用暴露的ASP.NET机器密钥实施未授权访问
网络·后端·asp.net
tomorrow.hello6 小时前
Java并发测试工具
java·开发语言·测试工具
晓13136 小时前
JavaScript加强篇——第四章 日期对象与DOM节点(基础)
开发语言·前端·javascript
老胖闲聊6 小时前
Python I/O 库【输入输出】全面详解
开发语言·python
张小洛6 小时前
Spring AOP 是如何生效的(入口源码级解析)?
java·后端·spring
我是前端小学生6 小时前
Rust中的Vec数据结构介绍
rust
why技术7 小时前
也是出息了,业务代码里面也用上算法了。
java·后端·算法
她说人狗殊途7 小时前
java.net.InetAddress
java·开发语言