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!();
相关推荐
canonical_entropy6 分钟前
DDD本质论:从哲学到数学,再到工程实践的完整指南之实践篇
java·后端·领域驱动设计
Madison-No716 分钟前
【C++】探秘string的底层实现
开发语言·c++
该用户已不存在28 分钟前
别再用 if err != nil 了,学会这几个技巧,假装自己是Go大神
后端·go
40 分钟前
从0开始搭建web应用
后端
Ray6643 分钟前
guide-rpc-framework笔记(四):网络编程
后端
Moonbit1 小时前
安装Wasm版的MoonBit工具链
后端·node.js·webassembly
法欧特斯卡雷特1 小时前
从 Kotlin 编译器 API 的变化开始: 2.2.2X -> 2.3.0-Beta1
后端·架构·开源
zjjuejin1 小时前
Maven 现代开发流程的集成
java·后端·maven
lly2024061 小时前
AJAX JSON 实例
开发语言
QiZhang | UESTC1 小时前
JAVA算法练习题day27
java·开发语言·c++·算法·leetcode·hot100