3.3.1 扩展外来类型
01-扩展外来类型 — Comprehensive Rust
2 分钟阅读
译文 · 基于 Comprehensive Rust
有时希望给外来类型扩展新方法。例如,让代码能用方法调用语法检查字符串是否为回文:s.is_palindrome()。
自然会想到写一个 impl 块:
| |
但 Rust 编译器不允许这样做。你可以用扩展 trait 模式绕过这一限制。
Rust 中的项(无论是 trait 还是类型)称为:
- 外来的(foreign),若未在当前 crate 中定义
- 本地的(local),若在当前 crate 中定义
这一区分对 一致性与孤儿规则 有重要影响,我们将在本节中探讨。
编译示例以展示编译器报错。
强调编译器错误信息如何把你引向扩展 trait 模式。
解释 Rust 中许多类型系统限制旨在防止歧义。
若允许在外来类型上定义新的固有方法会怎样?依赖树中不同 crate 可能在同一外来类型上用同名定义不同方法。
一旦存在歧义空间,就必须有消歧方式。若隐式消歧,可能导致令人惊讶或意外的行为。若显式消歧,会增加阅读代码时的认知负担。
此外,每当某个 crate 在外来类型上定义新的固有方法,就可能在你的代码中引发编译错误,因为你可能被迫引入显式消歧。
Rust 选择彻底禁止在外来类型上定义新的固有方法,从而避免该问题。
其他语言(如 Kotlin、C#、Swift)允许向已有类型添加方法,常称为「扩展方法」。这在潜在歧义与全局推理需求方面带来不同权衡。
01-扩展外来类型 — Comprehensive Rust
02-方法解析冲突 — Comprehensive Rust
03-Trait 方法冲突 — Comprehensive Rust
04-扩展其他 Trait — Comprehensive Rust
05-该不该定义扩展 Trait? — Comprehensive Rust