From b2df0688154857964be81c667eacc17c44468a6f Mon Sep 17 00:00:00 2001 From: W2Q3Q1 <72857495+W2Q3Q1@users.noreply.github.com> Date: Tue, 7 Jan 2025 19:51:59 +0800 Subject: [PATCH] Update macro.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改一个错误的描述。 --- src/advance/macro.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/advance/macro.md b/src/advance/macro.md index 92570a8c..f4713bc3 100644 --- a/src/advance/macro.md +++ b/src/advance/macro.md @@ -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