14.rust宏使用详解

一、前言

rust中的宏与C/C++中的宏是非常不一样的存在,C/C++中的宏仅仅只是简单的“文本替换”而已,而rust中的宏却可以被应用在“语法树”(token tree)上。

所谓“语法树”,是编译器根据该语言的语法规则、从你写的代码文件中所构建出来的一种树形结构,可以用于方便的分析代码语法,从而让编译器更加容易判断你的写的代码是否有错误、以及可能的修复方式等等。

这涉及到“编译原理”的相关理论知识,它是一门很难的课程,但好在我们并不需要自己开发语法分析器,所以是不需要去学习如何根据代码去生成一颗语法树的。

rust中的宏便是利用了rust编译器生成的这颗语法树来实现一些非常强大的功能,专业点来说,它实现了非常好的元编程操作方式。

二、基本使用

rust中一共提供了两种类型的宏:

  1. 声明式宏:比如println!就是一个声明式宏,常被用来移除重复的代码,和函数功能有点像,不同之处在于它会将编译期间生成的代码复制到使用该宏的位置。
  2. 过程宏:允许让你直接操作rust代码的抽象语法树,可以提供一些非常高级的功能,常见的就是#[drive(Debug)],这里的drive就是官方写的过程宏,可以让我们非常方便的实现某个trait

1.声明式宏

首先是声明式宏的用法,它其实和rust中的match语法很像,使用的关键字是:macro_rules!

虽然它没有“过程宏”强大,但其提供了非常容易使用的接口让我们可以快速的移除重复代码。

一个简单的声明式宏写法如下:

macro_rules! add {
    // 类似于match
    ($a:expr,$b:expr) => {
        {
            //使用传入的变量生成代码
            $a + $b
        }
    };
}

macro_rules!后面紧跟着的是宏的名字,然后就是宏的内容{}

其中宏的内容其实和match非常像,你可以写多个类似()=>{}这样的语句分支,只有当宏根据参数匹配到合适的语句分支、才会去生成对应分支下的代码。

比如上面的代码中,我暂时只写了一个分支语句,该分支的参数为两个变量$a$b,其类型为expr,表示这两个变量都是“表达式”。

注意:宏中的变量需要在前面添加$符号用于标识。

然后看到该分支语句中的内容,写了一个{},该{}内部就是让两个表达式相加。

使用方式很简单:

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux