@@ -166,7 +166,7 @@ impl String {
166166
167167#### 覆盖实现 (Covered Implementations)
168168
169- 在一些有限的情况下, 我们希望为一个外来类型实现一个外来` trait ` , 而孤儿规则通常不允许这样做. 最简单的例子是当你想编写类似` impl From<MyType> for Vec<i32> ` 的东西. 在这里, ` From ` ` trait ` 是外来的, ` Vec ` 类型也是, 但没有违反一致性的危险. 这是因为冲突的实现只能通过标准库中的覆盖实现来添加(标准库不能以其他方式命名` MyType ` ), 这无论如何是一个破坏性的改变.
169+ 在一些有限的情况下, 我们希望为一个外来类型实现一个外来` trait ` , 而孤儿规则通常不允许这样做. 最简单的例子是当你想编写类似` impl From<MyType> for Vec<i32> ` 的东西. 在这里, ` From trait ` 是外来的, ` Vec ` 类型也是, 但没有违反一致性的危险. 这是因为冲突的实现只能通过标准库中的覆盖实现来添加(标准库不能以其他方式命名` MyType ` ), 这无论如何是一个破坏性的改变.
170170
171171为了允许这些类型的实现, 孤儿规则包含了一个狭义的豁免, 允许在一组非常特殊的情况下为外部类型实现外部` trait ` . 具体来说, 只有当至少一个` Ti ` 是本地类型, 并且在第一个这样的` Ti ` 之前没有` T ` 是泛型类型` P1..=Pn ` , 才允许为` T0 ` 给定` impl<P1..=Pn> ForeignTrait<T1..=Tn> for T0 ` . 泛型类型参数(Ps)允许出现在` T0..Ti ` 中, 只要它们被某种中间类型所覆盖. 如果` T ` 作为其他类型的类型参数出现(比如 ` Vec<T> ` ), 那么会覆盖它, 但如果它独立存在(只有 ` T ` ),或者只是出现在基本类型(比如 ` &T ` )后面, 则不会覆盖它. 因此, 清单 2-4 中的所有实现都是有效的.
172172
@@ -245,7 +245,7 @@ impl Debug for AnyIterable
245245
246246并非所有` impl Trait ` 的实例都使用存在性类型. 如果在函数的参数位置使用` impl Trait ` , 它实际上只是该函数的一个未命名的泛型参数的缩写. 例如, ` fn foo(s: impl ToString) ` 其实是` fn foo<S: ToString>(s: S) ` 的语法糖.
247247
248- 当你实现有关联类型的` trait ` 时, 存在性类型就派上用场. 例如, 设想你正在实现` IntoIterator ` ` trait ` . 它有一个关联类型` IntoIter ` , 持有相关类型可以转换成的迭代器类型. 有了存在性类型, 你就不需要为` IntoIter ` 定义一个单独的迭代器类型. 相反, 你可以将关联类型定义为` impl Iterator<Item = Self::Item> ` , 并且只需在` fn into_iter(self) ` 中写入一个求值为` Iterator ` 的表达式, 比如通过某个现有迭代器类型上使用` maps ` 和` filters ` .
248+ 当你实现有关联类型的` trait ` 时, 存在性类型就派上用场. 例如, 设想你正在实现` IntoIterator trait ` . 它有一个关联类型` IntoIter ` , 持有相关类型可以转换成的迭代器类型. 有了存在性类型, 你就不需要为` IntoIter ` 定义一个单独的迭代器类型. 相反, 你可以将关联类型定义为` impl Iterator<Item = Self::Item> ` , 并且只需在` fn into_iter(self) ` 中写入一个求值为` Iterator ` 的表达式, 比如通过某个现有迭代器类型上使用` maps ` 和` filters ` .
249249
250250存在性类型还提供了一个很便利的特性: 它们允许你执行零成本的类型清除. 你可以使用存在性类型来隐藏底层的具体类型, 而不是仅仅因为它们出现在公共签名中就导出辅助类型--` iterators ` 和` future ` 就是这种常见的例子. 接口的用户只能看到相关类型所实现的` trait ` , 而具体类型则作为只是一个实现细节. 这不仅简化了接口, 还能让你随心所欲地更改实现, 而不会破坏未来的下游的代码.
251251
0 commit comments