Rust 的宏

首先, 我感觉 Rust 的宏是非常强大的, 可以根据 match 有不同的实现,但是它也是极其让人,起码是让我纠结的和费解的, 我希望能够一点点的弄懂他

文档来看

// 定义宏的语法
macro_rules! vec {
  // 这里的 * 感觉是一种连续的匹配值
    ( $( $x:expr ),* ) => {
        {
            let mut temp_vec = Vec::new();
            // $()*的语法在我看来就是一种迭代器,让我们迭代所有的匹配结果
            $(
                temp_vec.push($x);
            )*
            temp_vec
        }
    };
}

在一些复杂的宏中, 甚至用到了一些递归的写法
我们在 匹配的时候发现 匹配到的值后面有 :expr, 文档中也给出了一系列规则

ident: 标识符,用来表示函数或变量名
expr: 表达式
block: 代码块,用花括号包起来的多个语句
pat: 模式,普通模式匹配(非宏本身的模式)中的模式,例如 Some(t), (3, 'a', _)
path: 路径,注意这里不是操作系统中的文件路径,而是用双冒号分隔的限定名(qualified name),如 std::cmp::PartialOrd
tt: 单个语法树
ty: 类型,语义层面的类型,如 i32, char
item: 条目,
meta: 元条目
stmt: 单条语句,如 let a = 42;

#[macro_use] 表示子模块的宏可以被父模块调用
#[macro_export] 表示可以被其他的 crate 调用
$crate 在宏中表示该模块

实例解析

error_chain 这个类库就是一个使用宏的范例,我们今天就来看一下
这个库的主要功能就是通过简单的设置,让宏来完成所有重复的代码

基本的实现就是 通过一步步的宏的迭代,把需要的参数排序并且解析出来,之后再通过解析出来的参数,组合并且返回相应的代码块,代码块中已经把 错误类型, 错误文档, 错误代码 全部都自动组合好

你可能感兴趣的:(Rust 的宏)