|
|
|
@ -119,15 +119,28 @@ macro_rules! vec {
|
|
|
|
|
|
|
|
|
|
首先,我们使用圆括号 `()` 将整个宏模式包裹其中。紧随其后的是 `$()`,跟括号中模式相匹配的值(传入的 Rust 源代码)会被捕获,然后用于代码替换。在这里,模式 `$x:expr` 会匹配任何 Rust 表达式并给予该模式一个名称:`$x`。
|
|
|
|
|
|
|
|
|
|
`$()` 之后的逗号说明在 `$()` 所匹配的代码的后面会有一个可选的逗号分隔符,紧随逗号之后的 `*` 说明 `*` 之前的模式会被匹配零次或任意多次(类似正则表达式)。
|
|
|
|
|
`$()` 之后的逗号说明 `$()` 所匹配的代码使用逗号分隔符分割,紧随逗号之后的 `*` 说明 `*` 之前的模式(`$()`内的部分)会被匹配零次或任意多次(类似正则表达式)(且以逗号分割)。
|
|
|
|
|
|
|
|
|
|
当我们使用 `vec![1, 2, 3]` 来调用该宏时,`$x` 模式将被匹配三次,分别是 `1`、`2`、`3`。为了帮助大家巩固,我们再来一起过一下:
|
|
|
|
|
|
|
|
|
|
1. `$()` 中包含的是模式 `$x:expr`,该模式中的 `expr` 表示会匹配任何 Rust 表达式,并给予该模式一个名称 `$x`
|
|
|
|
|
2. 因此 `$x` 模式可以跟整数 `1` 进行匹配,也可以跟字符串 "hello" 进行匹配: `vec!["hello", "world"]`
|
|
|
|
|
3. `$()` 之后的逗号,意味着`1` 和 `2` 之间可以使用逗号进行分割,也意味着 `3` 既可以没有逗号,也可以有逗号:`vec![1, 2, 3,]`
|
|
|
|
|
3. `$()` 之后的逗号,意味着 `1` 、 `2` 和 `3` 之间使用逗号进行分割
|
|
|
|
|
4. `*` 说明之前的模式可以出现零次也可以任意次,这里出现了三次
|
|
|
|
|
|
|
|
|
|
__需要注意的是,此处简化的 `vec!` 实现中, `3` 后面是不能继续接逗号的( `vec![1, 2, 3]` 合法,但 `vec![1, 2, 3,]` 不合法),要匹配最后一个可有可无的逗号,可参考Rust官方的 `vec!` 宏定义,关键代码如下:__
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
($($x:expr),+ $(,)?) => (
|
|
|
|
|
<[_]>::into_vec(
|
|
|
|
|
// This rustc_box is not required, but it produces a dramatic improvement in compile
|
|
|
|
|
// time when constructing arrays with many elements.
|
|
|
|
|
#[rustc_box]
|
|
|
|
|
$crate::boxed::Box::new([$($x),+])
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
接下来,我们再来看看与模式相关联、在 `=>` 之后的代码:
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|