以下文章是根据官网教程学习:
教程地址如下:
https://doc.rust-lang.org/book/ch19-06-macros.html
我喜欢先写代码,再总结。所以直入主题。
使用macro_rules
声明宏
目录结构
├── macros.rs
└── main.rs
macros.rs
#[macro_export] // ① 表示下面的宏定义对其他包也是可见的
macro_rules! vec { // ② 定义一个名为 vec 的宏
// ③
// 首先使用一对圆括号包裹起来。
// $( $x:expr ) : 表被匹配病捕获的值最终会生成替换代码
// $x:expr : 表可以匹配任意Rust表达式,将其命名为$x
// $(), : $()之后的逗号 表逗号分隔符在捕获代码的后面
// * : 逗号后的* 表之前的模式能够匹配零个或多个。
( $( $x:expr ),* ) => {
{
let mut temp_vec = Vec::new();
$(
// ④ 将匹配到表达式替换如下。
temp_vec.push($x);
)*
temp_vec
}
};
}
main.rs
#[macro_use] // ⑤ 表: 导入宏
pub mod macros;
fn main() {
let _v: Vec<u32> = vec![1, 2, 3];
println!("{:?}", _v);
}
最终 vec![1, 2, 3]
宏代码将生成如下代码:
{
let mut temp_vec = Vec::new();
temp_vec.push(1);
temp_vec.push(2);
temp_vec.push(3);
temp_vec
}
## 过程宏
看了官网的教程也是云里雾里的,不过有一句话很重要,过程宏不需要像声明宏根据模式匹配来替换代码。
过程宏有以下三种方式:
- 自定义派生宏 custom derive
- 属性宏
- 函数宏
因为过程宏,自己也没有搞明白,就不写了。我直接贴上相关的文章链接和代码。
https://rustcc.cn/article?id=0a7aa603-8aa7-41c1-acfa-4b2e0c91e4c9
https://www.cnblogs.com/gyc567/p/12045350.html
Source Code: