Update ch19-06-macros.md

This commit is contained in:
庄秋彬 2020-02-26 23:47:16 +08:00 committed by GitHub
parent c6f8f09f92
commit e02a707984
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -14,7 +14,7 @@
### 宏和函数的区别
从根本上来说,宏是一种为写其他代码而写代码的方式,即所谓的 **元编程***metaprogramming*)。在附录 C 中会探讨 `derive` 属性,其生成各种 trait 的实现。我们也在本书中使用过 `println!` 宏和 `vec!` 宏。所有的这些宏 **展开**生成比你手写更多的代码。
从根本上来说,宏是一种为写其他代码而写代码的方式,即所谓的 **元编程***metaprogramming*)。在附录 C 中会探讨 `derive` 属性,其生成各种 trait 的实现。我们也在本书中使用过 `println!` 宏和 `vec!` 宏。所有的这些宏 **展开** 的方式来生成比你手写出的更多的代码。
元编程对于减少大量编写和维护的代码是非常有用的,它也扮演了函数的角色。但宏有一些函数所没有的附加能力。
@ -28,7 +28,7 @@
Rust 最常用的宏形式是 **声明宏***declarative macros*)。它们有时也被称为 “macros by example”、“`macro_rules!` 宏” 或者就是 “macros”。其核心概念是声明宏允许我们编写一些类似 Rust `match` 表达式的代码。正如在第六章讨论的那样,`match` 表达式是控制结构,其接收一个表达式,与表达式的结果进行模式匹配,然后根据模式匹配执行相关代码。宏也将一个值和包含相关代码的模式进行比较;此种情况下,该值是传递给宏的 Rust 源代码字面值,模式用于和传递给宏的源代码进行比较,同时每个模式的相关代码则用于替换传递给宏的代码。所有这一切都发生于编译时。
可以使用 `macro_rules!` 来定义宏。让我们通过查看 `vec!` 宏定义来探索如何使用 `macro_rules!` 结构。第八章讲述了如何使用 `vec!` 宏来生成一个给定值的 vector。例如下面的宏用三个整数创建一个 vector `
可以使用 `macro_rules!` 来定义宏。让我们通过查看 `vec!` 宏定义来探索如何使用 `macro_rules!` 结构。第八章讲述了如何使用 `vec!` 宏来生成一个给定值的 vector。例如下面的宏用三个整数创建一个 vector
```rust
let v: Vec<u32> = vec![1, 2, 3];
@ -64,7 +64,7 @@ macro_rules! vec {
接着使用 `macro_rules!` 和宏名称开始宏定义,且所定义的宏并 *不带* 感叹号。名字后跟大括号表示宏定义体,在该例中宏名称是 `vec`
`vec!` 宏的结构和 `match` 表达式的结构类似。此处有一个单边模式 `( $( $x:expr ),* )` ,后跟 `=>` 以及和模式相关的代码块。如果模式匹配,该相关代码块将被执行。假设这只是这个宏中的模式,且只有一个有效匹配,其他任何匹配都是错误的。更复杂的宏会有多个单边模式。
`vec!` 宏的结构和 `match` 表达式的结构类似。此处有一个单边模式 `( $( $x:expr ),* )` ,后跟 `=>` 以及和模式相关的代码块。如果模式匹配,该相关代码块将被执行。假设这是这个宏中唯一的模式,则只有这一种有效匹配,其他任何匹配都是错误的。更复杂的宏会有多个单边模式。
宏定义中有效模式语法和在第十八章提及的模式语法是不同的,因为宏模式所匹配的是 Rust 代码结构而不是值。回过头来检查下示例 19-28 中模式片段什么意思。对于全部的宏模式语法,请查阅[参考]。