mirror of
https://github.com/KaiserY/trpl-zh-cn
synced 2024-11-09 08:51:18 +08:00
fix autocorrect
This commit is contained in:
parent
a6a81345e6
commit
e867b0a913
@ -141,7 +141,7 @@ Tony Hoare,null 的发明者,在他 2009 年的演讲 “Null References: Th
|
|||||||
|
|
||||||
然而,空值尝试表达的概念仍然是有意义的:空值是一个因为某种原因目前无效或缺失的值。
|
然而,空值尝试表达的概念仍然是有意义的:空值是一个因为某种原因目前无效或缺失的值。
|
||||||
|
|
||||||
问题不在于概念而在于具体的实现。为此,Rust 并没有空值,不过它确实拥有一个可以编码存在或不存在概念的枚举。这个枚举是 `Option<T>`,而且它[定义于标准库中][option]<!-- ignore -->,如下:
|
问题不在于概念而在于具体的实现。为此,Rust 并没有空值,不过它确实拥有一个可以编码存在或不存在概念的枚举。这个枚举是 `Option<T>`,而且它[定义于标准库中][option]<!-- ignore -->,如下:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
enum Option<T> {
|
enum Option<T> {
|
||||||
|
@ -194,7 +194,7 @@ fn some_function<T: Display + Clone, U: Clone + Debug>(t: &T, u: &U) -> i32 {
|
|||||||
|
|
||||||
### 使用 trait bound 有条件地实现方法
|
### 使用 trait bound 有条件地实现方法
|
||||||
|
|
||||||
通过使用带有 trait bound 的泛型参数的 `impl` 块,可以有条件地只为那些实现了特定 trait 的类型实现方法。例如,示例 10-15 中的类型 `Pair<T>` 总是实现了 `new` 方法并返回一个 `Pair<T>` 的实例(回忆一下第五章的 ["定义方法"][methods] 部分,`Self` 是一个 `impl` 块类型的类型别名(type alias),在这里是 `Pair<T>`)。不过在下一个 `impl` 块中,只有那些为 `T` 类型实现了 `PartialOrd` trait (来允许比较) **和** `Display` trait (来启用打印)的 `Pair<T>` 才会实现 `cmp_display` 方法:
|
通过使用带有 trait bound 的泛型参数的 `impl` 块,可以有条件地只为那些实现了特定 trait 的类型实现方法。例如,示例 10-15 中的类型 `Pair<T>` 总是实现了 `new` 方法并返回一个 `Pair<T>` 的实例(回忆一下第五章的 ["定义方法"][methods] 部分,`Self` 是一个 `impl` 块类型的类型别名(type alias),在这里是 `Pair<T>`)。不过在下一个 `impl` 块中,只有那些为 `T` 类型实现了 `PartialOrd` trait(来允许比较) **和** `Display` trait(来启用打印)的 `Pair<T>` 才会实现 `cmp_display` 方法:
|
||||||
|
|
||||||
```rust,noplayground
|
```rust,noplayground
|
||||||
{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/src/lib.rs}}
|
{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/src/lib.rs}}
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<span class="caption">示例 12-16:刚好足够使测试通过编译的 `search` 函数定义</span>
|
<span class="caption">示例 12-16:刚好足够使测试通过编译的 `search` 函数定义</span>
|
||||||
|
|
||||||
注意需要在 `search` 的签名中定义一个显式生命周期 `'a` 并用于 `contents` 参数和返回值。回忆一下 [第十章][ch10-lifetimes] 中讲到生命周期参数指定哪个参数的生命周期与返回值的生命周期相关联。在这个例子中,我们表明返回的 vector 中应该包含引用参数 `contents`(而不是参数`query`) slice 的字符串 slice。
|
注意需要在 `search` 的签名中定义一个显式生命周期 `'a` 并用于 `contents` 参数和返回值。回忆一下 [第十章][ch10-lifetimes] 中讲到生命周期参数指定哪个参数的生命周期与返回值的生命周期相关联。在这个例子中,我们表明返回的 vector 中应该包含引用参数 `contents`(而不是参数`query`)slice 的字符串 slice。
|
||||||
|
|
||||||
换句话说,我们告诉 Rust 函数 `search` 返回的数据将与 `search` 函数中的参数 `contents` 的数据存在的一样久。这是非常重要的!为了使这个引用有效那么 **被** slice 引用的数据也需要保持有效;如果编译器认为我们是在创建 `query` 而不是 `contents` 的字符串 slice,那么安全检查将是不正确的。
|
换句话说,我们告诉 Rust 函数 `search` 返回的数据将与 `search` 函数中的参数 `contents` 的数据存在的一样久。这是非常重要的!为了使这个引用有效那么 **被** slice 引用的数据也需要保持有效;如果编译器认为我们是在创建 `query` 而不是 `contents` 的字符串 slice,那么安全检查将是不正确的。
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ Rust 的 **闭包**(*closures*)是可以保存在一个变量中或作为参
|
|||||||
|
|
||||||
`main` 函数中定义的 `store` 还剩有两件蓝衬衫和一件红衬衫可在限量版促销活动中赠送。我们用一个期望获得红衬衫和一个没有期望的用户来调用 `giveaway` 方法。
|
`main` 函数中定义的 `store` 还剩有两件蓝衬衫和一件红衬衫可在限量版促销活动中赠送。我们用一个期望获得红衬衫和一个没有期望的用户来调用 `giveaway` 方法。
|
||||||
|
|
||||||
再次强调,这段代码可以有多种实现方式。这里为了专注于闭包,我们会继续使用已经学习过的概念,除了 `giveaway` 方法体中使用了闭包。`giveaway` 方法获取了 `Option<ShirtColor>` 类型作为用户的期望颜色并在 `user_preference` 上调用 `unwrap_or_else` 方法。 [`Option<T>` 上的方法 `unwrap_or_else`][unwrap-or-else] 由标准库定义,它获取一个没有参数、返回值类型为 `T` (与 `Option<T>` 的 `Some` 成员所存储的值的类型一样,这里是 `ShirtColor`)的闭包作为参数。如果 `Option<T>` 是 `Some` 成员,则 `unwrap_or_else` 返回 `Some` 中的值。 如果 `Option<T>` 是 `None` 成员, 则 `unwrap_or_else` 调用闭包并返回闭包的返回值。
|
再次强调,这段代码可以有多种实现方式。这里为了专注于闭包,我们会继续使用已经学习过的概念,除了 `giveaway` 方法体中使用了闭包。`giveaway` 方法获取了 `Option<ShirtColor>` 类型作为用户的期望颜色并在 `user_preference` 上调用 `unwrap_or_else` 方法。 [`Option<T>` 上的方法 `unwrap_or_else`][unwrap-or-else] 由标准库定义,它获取一个没有参数、返回值类型为 `T` (与 `Option<T>` 的 `Some` 成员所存储的值的类型一样,这里是 `ShirtColor`)的闭包作为参数。如果 `Option<T>` 是 `Some` 成员,则 `unwrap_or_else` 返回 `Some` 中的值。如果 `Option<T>` 是 `None` 成员,则 `unwrap_or_else` 调用闭包并返回闭包的返回值。
|
||||||
|
|
||||||
我们将被闭包表达式 `|| self.most_stocked()` 用作 `unwrap_or_else` 的参数。这是一个本身不获取参数的闭包(如果闭包有参数,它们会出现在两道竖杠之间)。闭包体调用了 `self.most_stocked()`。我们在这里定义了闭包,而 `unwrap_or_else` 的实现会在之后需要其结果的时候执行闭包。
|
我们将被闭包表达式 `|| self.most_stocked()` 用作 `unwrap_or_else` 的参数。这是一个本身不获取参数的闭包(如果闭包有参数,它们会出现在两道竖杠之间)。闭包体调用了 `self.most_stocked()`。我们在这里定义了闭包,而 `unwrap_or_else` 的实现会在之后需要其结果的时候执行闭包。
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
#### 内部可变性的用例:mock 对象
|
#### 内部可变性的用例:mock 对象
|
||||||
|
|
||||||
有时在测试中程序员会用某个类型替换另一个类型,以便观察特定的行为并断言它是被正确实现的。这个占位符类型被称为 **测试替身**(_test double_)。就像电影制作中的替身演员(_stunt double_)一样,替代演员完成高难度的场景。测试替身在运行测试时替代某个类型。**mock 对象** 是特定类型的测试替身,它们记录测试过程中发生了什么以便可以断言操作是正确的。
|
有时在测试中程序员会用某个类型替换另一个类型,以便观察特定的行为并断言它是被正确实现的。这个占位符类型被称为 **测试替身**(_test double_)。就像电影制作中的替身演员 (_stunt double_) 一样,替代演员完成高难度的场景。测试替身在运行测试时替代某个类型。**mock 对象** 是特定类型的测试替身,它们记录测试过程中发生了什么以便可以断言操作是正确的。
|
||||||
|
|
||||||
虽然 Rust 中的对象与其他语言中的对象并不是一回事,Rust 也没有像其他语言那样在标准库中内建 mock 对象功能,不过我们确实可以创建一个与 mock 对象有着相同功能的结构体。
|
虽然 Rust 中的对象与其他语言中的对象并不是一回事,Rust 也没有像其他语言那样在标准库中内建 mock 对象功能,不过我们确实可以创建一个与 mock 对象有着相同功能的结构体。
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user