第5章 Trait与泛型判例


第 5 章 · Trait 与泛型判例

本章要回答的三个问题:不同类型之间的共同行为契约怎么立?一份代码怎么安全地服务多种类型?编译期多态与运行期多态各在什么案子里用?

为什么要有这一章

第 4 章建好了数据卷宗,但司法系统里还有"判例法":不管案卷是纸质还是电子,都要能"归档"——这是行为契约,即 Trait。而书记员写一次归档流程应当适用于所有案卷类型——这是泛型。两者结合(Trait 约束泛型)构成 Rust 的抽象主力,且抽象在编译期展开,零运行时成本。

读完能解决什么

  • 定义 Trait、为自有类型实现 Trait、用 Trait 约束写通用函数;
  • 分清泛型静态派发与 Trait 对象动态派发的适用边界;
  • 读懂常见 trait bound 签名并自己写出 Display、From 等标准实现。

各节怎么分工

节 回答哪个问题 关键产出
5.1 Trait 定义与实现 契约怎么立、怎么履行 默认方法、标准库常用 Trait
5.2 泛型 一份代码多种类型 单态化、Trait 约束三写法
5.3 Trait 对象 运行期多态怎么做 dyn 与泛型对比表、对象安全

先决条件

  • 第 3、4 章的引用与结构体基础;第 1 章讲过的"单态化"编译阶段在这里兑现。

往下走到哪

Trait 是后面各章的地基:第 6 章错误处理靠 From 与 Display,第 8 章并发安全靠 Send 与 Sync,第 9 章派生宏自动生成 Trait 实现。

本章判例速查

trait 与泛型的报错集中在"约束不满足"与"不兼容"两条线上。

报错 案情 修法方向
E0277 类型缺 trait 实现 补 impl、换类型或加约束
E0038 trait 不能做 dyn 对象 去 Self 返回、泛型方法加 Sized 豁免
E0308 + 泛型 T 绑定到两个不同类型 统一类型或 turbofish
E0210 违反孤儿规则 新类型包装后再 impl

静态与动态的选型卡

判据 静态派发(泛型) 动态派发(dyn)
类型成员 编译期已知 运行期生长
调用成本 可内联,零间接 一次 vtable 寻址
代码体积 每类型一份,膨胀 一份
二进制边界 跨边界需单态化 天然适用
典型席位 算法、迭代器 插件、事件总线、异构集合

工程默认值是泛型;只有在"需要把不同类型装进同一容器"或"编译边界不许泄漏泛型"时退到 dyn。两者混用也常见——对内泛型求性能,对外 dyn 求稳定接口。

与下一章的衔接

trait 体系里有一类特殊判例尚未开庭:那些表达"成功或失败"的 trait 与类型——Result 就是标准库中最著名的 enum,? 运算符则是对 From trait 的一次语法级引用。第 6 章错误处理庭实质上是本章法条在可靠性辖区的适用,读的时候留意 From 与 ? 的联动即可。

选型口诀

能用泛型不写 dyn,能用关联类型不堆参数,能收窄约束不放宽。三个"能"字背后是同一价值排序:编译期信息越足,代码越快越好查。反向的三个信号——异构集合、运行期注册、二进制边界求稳——出现任意一条,才把具体类型换 Box<dyn Trait>。口诀配前文的选型卡,本章的工程决策就闭环了。

三道自测题

一问:默认方法能调用同 trait 的另一个方法吗?答:能,且运行时分派到实现方版本,Iterator 生态由此筑成。二问:fn f(x: &dyn Trait) 与 fn f<T: Trait>(x: &T) 的机器码差异?答:前者一份、经 vtable 间接调用;后者每类型一份、可内联。三问:孤儿规则禁止什么?答:为外部类型实现外部 trait,防止冲突 impl;解法是新类型包装。三题过线,trait 体系就从语法升级为设计工具。

作者与出处
原作者:灏天文库
来源:平台策划编纂
整理人: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U