This commit is contained in:
e2hang
2025-10-05 23:51:24 +08:00
parent 1f9543c16c
commit 23f17bfc2c
113 changed files with 1236 additions and 0 deletions

124
Macro/readme.md Normal file
View File

@@ -0,0 +1,124 @@
完全可以,我们来系统讲一下 `macro_rules!`**宏变量匹配类型**,也就是你说的除了 `expr` 还能匹配什么。
---
## 1⃣ 基本宏变量语法
```rust
$变量名:匹配类型
```
* `$` → 宏变量前缀
* `变量名` → 自己命名
* `匹配类型` → Rust 定义的一些匹配规则,告诉宏要匹配什么类型的语法单元
---
## 2⃣ 常用匹配类型
| 匹配类型 | 描述 | 示例 |
| --------- | --------------- | --------------------------------------- |
| `expr` | 表达式 | `5 + 3`, `a * b`, `func(1)` |
| `ident` | 标识符 | `x`, `my_var` |
| `ty` | 类型 | `i32`, `Vec<String>` |
| `pat` | 模式 | `Some(x)`, `(a, b)` |
| `stmt` | 语句 | `let x = 1;` |
| `block` | 代码块 | `{ let x = 1; x+2 }` |
| `meta` | 元属性 | `derive(Debug)` |
| `tt` | Token Tree最通用 | 单个标记或标记组,几乎可以匹配任何东西 |
| `path` | 路径 | `std::io::Result`, `crate::module::Foo` |
| `literal` | 字面量 | `"hello"`, `42`, `3.14` |
---
### 3⃣ 示例
#### 表达式匹配
```rust
macro_rules! add {
($a:expr, $b:expr) => {
$a + $b
};
}
let x = add!(1 + 2, 3 * 4); // 匹配复杂表达式
```
#### 类型匹配
```rust
macro_rules! make_default {
($t:ty) => {
<$t>::default()
};
}
let v: Vec<i32> = make_default!(Vec<i32>);
```
#### 标识符匹配
```rust
macro_rules! create_var {
($name:ident) => {
let $name = 42;
};
}
create_var!(my_var);
println!("{}", my_var); // 输出 42
```
#### 语句匹配
```rust
macro_rules! repeat_stmt {
($s:stmt) => {
$s
$s
};
}
repeat_stmt!(println!("Hi");) // 会打印两次 Hi
```
#### 代码块匹配
```rust
macro_rules! run_block {
($b:block) => {
println!("Before");
$b
println!("After");
};
}
run_block!({
println!("Inside");
});
```
输出:
```
Before
Inside
After
```
---
### 4⃣ 小结
* `expr` 只能匹配表达式
* Rust 宏提供了多种匹配类型(`ident`, `ty`, `pat`, `stmt`, `block`, `literal`, `tt` 等)
* `tt` 最通用,但匹配后需要自己处理结构
> 可以理解为:**每个匹配类型限制了宏能匹配的语法单元**,避免写宏时乱匹配或产生歧义
---
我可以画一张 **macro_rules! 匹配类型示意图**,把 `expr, ident, ty, pat, stmt, block, tt, literal` 的对应语法单元和示例都标出来,一目了然。
你希望我画吗?