3.3.4 扩展其他 Trait
2 分钟阅读
译文 · 基于 Comprehensive Rust
3.3.4 扩展其他 Trait
与类型类似,有时希望扩展外来 trait。特别是,给给定 trait 的所有实现者附加新方法。
| |
强调我们如何一次为多个类型添加新行为。可对字符串切片、数字和布尔值调用
.quoted(),因为它们都实现了Displaytrait。这种扩展 trait 模式变体使用 blanket 实现。
Blanket 实现为满足
impl块中指定 trait 约束的所有类型T实现某个 trait。本例中,唯一要求是T实现Displaytrait。引导学生注意
DisplayExt::quoted的实现:除了实现Display之外,我们不能对T做任何假设。所有逻辑必须要么使用Display的方法,要么使用不要求其他 trait 的函数/宏。例如,我们可以对
T调用format!,但不能调用.to_uppercase(),因为它不一定是String。我们可以对
T引入额外的 trait 约束,但这会限制能利用该扩展 trait 的类型集合。按惯例,扩展 trait 以它所扩展的 trait 命名,后接
Ext后缀。上例中为DisplayExt。有整类 crate 用新功能扩展标准库 trait。
itertoolscrate 提供扩展Iterator的Itertoolstrait。它添加许多迭代器适配器,如interleave和unique。它为用方法链构建的迭代器管道提供新的算法构件。
futurescrate 提供FutureExttrait,用新的组合子与辅助方法扩展Futuretrait。深入探索
库可用扩展 trait 区分稳定方法与实验性方法。
稳定方法是 trait 定义的一部分。
实验性方法通过另一库中定义的扩展 trait 提供,稳定性策略更宽松。一些实用方法在被证明有用且设计完善后,会被「提升」到核心 trait 定义中。
扩展 trait 可用于将 dyn 不兼容的 trait 一分为二:
- dyn 兼容的核心,仅包含满足 dyn 兼容性要求的方法。
- 扩展 trait,包含其余非 dyn 兼容的方法(例如带泛型参数的方法)。
实现核心 trait 的具体类型将能调用所有方法,这得益于扩展 trait 的 blanket impl。Trait 对象(
dyn CoreTrait)将能调用核心 trait 上的所有方法,以及扩展 trait 上不要求Self: Sized的那些方法。