主题
Trait
Trait 描述类型具备的行为。类型通过 impl Trait for Type 加入实现。泛型用 trait bound 约束「能做什么」,而不是继承层级。
rust
trait Summary {
fn summary(&self) -> String;
fn peek(&self) -> String {
self.summary()
}
}
impl Summary for User {
fn summary(&self) -> String {
self.name.clone()
}
}默认方法可以在 trait 里提供实现,类型只覆盖需要定制的部分。
派生与手写
#[derive(Debug, Clone, ...)] 由编译器按字段生成实现,字段类型也必须满足对应 trait。行为无法由字段直接推出时手写 impl,例如 Display、From。
标准库里项目中最常碰到的:
| Trait | 作用 |
|---|---|
Debug | 调试输出 {:?} |
Display | 用户可见文本 {} |
Clone / Copy | 显式复制 / 按位复制 |
Default | 默认值 |
From / TryFrom | 类型转换;? 依赖 From |
Iterator | for 循环与适配器 |
Drop | 离开作用域时的清理 |
Send / Sync | 跨线程移动 / 共享 |
Error | 可作为 Result 的 E |
静态分发与动态分发
rust
fn print_static(s: impl Summary) {
println!("{}", s.summary());
}
fn print_dyn(s: &dyn Summary) {
println!("{}", s.summary());
}impl Trait 和 <T: Summary> 在编译期单态化,零开销,生成代码按具体类型展开。dyn Trait 是胖指针(数据指针 + 虚表),运行时分发,对象大小不固定,适合异质集合。
dyn Trait 本身不满足 Sized,通常写成 &dyn Trait 或 Box<dyn Trait>。
孤儿规则
Trait 或类型至少有一个在当前 crate 定义,才能写 impl Trait for Type。不能为外部类型实现外部 trait。需要给外部类型加方法时,用本地 newtype 包一层。
常用写法
rust
fn dump<T: Summary + std::fmt::Debug>(value: T) {
println!("{:?} {}", value, value.summary());
}
impl From<u64> for UserId {
fn from(id: u64) -> Self {
Self(id)
}
}From 实现后自动获得 Into。应用代码优先 From / TryFrom,而不是散落转换函数。
