mirror of
https://github.com/KaiserY/trpl-zh-cn
synced 2024-11-09 08:51:18 +08:00
update ch19-06 close #391
This commit is contained in:
parent
07a840f7fa
commit
8b00f98009
@ -18,7 +18,7 @@
|
||||
|
||||
元编程对于减少大量编写和维护的代码是非常有用的,它也扮演了函数的角色。但宏有一些函数所没有的附加能力。
|
||||
|
||||
一个函数标签必须声明函数参数个数和类型。相比之下,宏只接受一个可变参数:用一个参数调用 `println!("hello")` 或用两个参数调用 `println!("hello {}", name)` 。而且,宏可以在编译器翻译代码前展开,例如,宏可以在一个给定类型上实现 trait 。因为函数是在运行时被调用,同时 trait 需要在运行时实现,所以函数无法像宏这样。
|
||||
一个函数标签必须声明函数参数个数和类型。相比之下,宏只接受一个可变参数:用一个参数调用 `println!("hello")` 或用两个参数调用 `println!("hello {}", name)` 。而且,宏可以在编译器翻译代码前展开,例如,宏可以在一个给定类型上实现 trait 。而函数则不行,因为函数是在运行时被调用,同时 trait 需要在编译时实现。
|
||||
|
||||
实现一个宏而不是函数的消极面是宏定义要比函数定义更复杂,因为你正在编写生成 Rust 代码的 Rust 代码。由于这样的间接性,宏定义通常要比函数定义更难阅读、理解以及维护。
|
||||
|
||||
@ -296,9 +296,9 @@ fn impl_hello_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||
|
||||
我们得到一个包含以 `ast.ident` 作为注解类型名字(标识符)的 `Ident` 结构体实例。示例 19-32 中的结构体表明当 `impl_hello_macro` 函数运行于示例 19-30 中的代码上时 `ident` 字段的值是 `"Pancakes"`。因此,示例 19-33 中 `name` 变量会包含一个 `Ident` 结构体的实例,当打印时,会是字符串 `"Pancakes"`,也就是示例 19-30 中结构体的名称。
|
||||
|
||||
`quote!` 让我们可以编写希望返回的 Rust diamagnetic。`quote!` 宏执行的直接结果并不是编译器所期望的并需要转换为 `TokenStream`。为此需要调用 `into` 方法,它会消费这个中间表示(intermediate representation,IR)并返回所需的 `TokenStream` 类型值。
|
||||
`quote!` 宏让我们可以编写希望返回的 Rust 代码。`quote!` 宏执行的直接结果并不是编译器所期望的并需要转换为 `TokenStream`。为此需要调用 `into` 方法,它会消费这个中间表示(intermediate representation,IR)并返回所需的 `TokenStream` 类型值。
|
||||
|
||||
这个宏也提供了一些非常酷的模板机制;我们可以写 `#name` ,然后 `quote!` 会以 名为 `name` 的变量值来替换它。你甚至可以做些与这个正则宏任务类似的重复事情。查阅 [`quote` crate 的文档][quote-docs] 来获取详尽的介绍。
|
||||
这个宏也提供了一些非常酷的模板机制;我们可以写 `#name` ,然后 `quote!` 会以名为 `name` 的变量值来替换它。你甚至可以做一些类似常用宏那样的重复代码的工作。查阅 [`quote` crate 的文档][quote-docs] 来获取详尽的介绍。
|
||||
|
||||
[quote-docs]: https://docs.rs/quote
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user