mirror of
https://github.com/KaiserY/trpl-zh-cn
synced 2024-11-14 04:41:49 +08:00
Merge pull request #550 from SpriteOvO/main
Remove a duplicate word, improve translation grammar and fix listing ids
This commit is contained in:
commit
85ba31063b
@ -155,7 +155,7 @@ fn main() {
|
||||
|
||||
这段代码创建了变量 `x` 和 `y`,与变量 `p` 中的 `x` 和 `y` 相匹配。其结果是变量 `x` 和 `y` 包含结构体 `p` 中的值。
|
||||
|
||||
也可以使用字面值作为结构体模式的一部分进行进行解构,而不是为所有的字段创建变量。这允许我们测试一些字段为特定值的同时创建其他字段的变量。
|
||||
也可以使用字面值作为结构体模式的一部分进行解构,而不是为所有的字段创建变量。这允许我们测试一些字段为特定值的同时创建其他字段的变量。
|
||||
|
||||
示例 18-14 展示了一个 `match` 语句将 `Point` 值分成了三种情况:直接位于 `x` 轴上(此时 `y = 0` 为真)、位于 `y` 轴上(`x = 0`)或不在任何轴上的点。
|
||||
|
||||
|
@ -79,7 +79,7 @@ fn returns_long_type() -> Thunk {
|
||||
|
||||
<span class="caption">示例 19-25: 引入类型别名 `Thunk` 来减少重复</span>
|
||||
|
||||
这样就读写起来就容易多了!为类型别名选择一个好名字也可以帮助你表达意图(单词 *thunk* 表示会在之后被计算的代码,所以这是一个存放闭包的合适的名字)。
|
||||
这样读写起来就容易多了!为类型别名选择一个好名字也可以帮助你表达意图(单词 *thunk* 表示会在之后被计算的代码,所以这是一个存放闭包的合适的名字)。
|
||||
|
||||
类型别名也经常与 `Result<T, E>` 结合使用来减少重复。考虑一下标准库中的 `std::io` 模块。I/O 操作通常会返回一个 `Result<T, E>`,因为这些操作可能会失败。标准库中的 `std::io::Error` 结构体代表了所有可能的 I/O 错误。`std::io` 中大部分函数会返回 `Result<T, E>`,其中 `E` 是 `std::io::Error`,比如 `Write` trait 中的这些函数:
|
||||
|
||||
@ -171,7 +171,7 @@ impl<T> Option<T> {
|
||||
}
|
||||
```
|
||||
|
||||
这里与示例 19-34 中的 `match` 发生了相同的情况:Rust 知道 `val` 是 `T` 类型,`panic!` 是 `!` 类型,所以整个 `match` 表达式的结果是 `T` 类型。这能工作是因为 `panic!` 并不产生一个值;它会终止程序。对于 `None` 的情况,`unwrap` 并不返回一个值,所以这些代码是有效。
|
||||
这里与示例 19-34 中的 `match` 发生了相同的情况:Rust 知道 `val` 是 `T` 类型,`panic!` 是 `!` 类型,所以整个 `match` 表达式的结果是 `T` 类型。这能工作是因为 `panic!` 并不产生一个值;它会终止程序。对于 `None` 的情况,`unwrap` 并不返回一个值,所以这些代码是有效的。
|
||||
|
||||
最后一个有着 `!` 类型的表达式是 `loop`:
|
||||
|
||||
|
@ -305,7 +305,7 @@ fn impl_hello_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||
|
||||
此处所使用的 `stringify!` 为 Rust 内置宏。其接收一个 Rust 表达式,如 `1 + 2` , 然后在编译时将表达式转换为一个字符串常量,如 `"1 + 2"` 。这与 `format!` 或 `println!` 是不同的,它计算表达式并将结果转换为 `String` 。有一种可能的情况是,所输入的 `#name` 可能是一个需要打印的表达式,因此我们用 `stringify!` 。 `stringify!` 编译时也保留了一份将 `#name` 转换为字符串之后的内存分配。
|
||||
|
||||
此时,`cargo build` 应该都能成功编译 `hello_macro` 和 `hello_macro_derive` 。我们将这些 crate 连接到示例 19-38 的代码中来看看过程宏的行为!在 *projects* 目录下用 `cargo new pancakes` 命令新建一个二进制项目。需要将 `hello_macro` 和 `hello_macro_derive` 作为依赖加到 `pancakes` 包的 *Cargo.toml* 文件中去。如果你正将 `hello_macro` 和 `hello_macro_derive` 的版本发布到 [crates.io](https://crates.io/) 上,其应为常规依赖;如果不是,则可以像下面这样将其指定为 `path` 依赖:
|
||||
此时,`cargo build` 应该都能成功编译 `hello_macro` 和 `hello_macro_derive` 。我们将这些 crate 连接到示例 19-30 的代码中来看看过程宏的行为!在 *projects* 目录下用 `cargo new pancakes` 命令新建一个二进制项目。需要将 `hello_macro` 和 `hello_macro_derive` 作为依赖加到 `pancakes` 包的 *Cargo.toml* 文件中去。如果你正将 `hello_macro` 和 `hello_macro_derive` 的版本发布到 [crates.io](https://crates.io/) 上,其应为常规依赖;如果不是,则可以像下面这样将其指定为 `path` 依赖:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
@ -313,7 +313,7 @@ hello_macro = { path = "../hello_macro" }
|
||||
hello_macro_derive = { path = "../hello_macro/hello_macro_derive" }
|
||||
```
|
||||
|
||||
把示例 19-38 中的代码放在 *src/main.rs* ,然后执行 `cargo run`:其应该打印 `Hello, Macro! My name is Pancakes!`。其包含了该过程宏中 `HelloMacro` trait 的实现,而无需 `pancakes` crate 实现它;`#[derive(HelloMacro)]` 增加了该 trait 实现。
|
||||
把示例 19-30 中的代码放在 *src/main.rs* ,然后执行 `cargo run`:其应该打印 `Hello, Macro! My name is Pancakes!`。其包含了该过程宏中 `HelloMacro` trait 的实现,而无需 `pancakes` crate 实现它;`#[derive(HelloMacro)]` 增加了该 trait 实现。
|
||||
|
||||
接下来,让我们探索一下其他类型的过程宏与自定义派生宏有何区别。
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user