This commit is contained in:
e2hang
2025-10-05 23:51:24 +08:00
parent 1f9543c16c
commit 23f17bfc2c
113 changed files with 1236 additions and 0 deletions

288
Trait/readme.md Normal file
View File

@@ -0,0 +1,288 @@
非常好 👍!
`trait` 是 Rust 中非常核心、非常强大的概念之一,几乎等价于 C++ 的「接口interface」或「抽象基类abstract base class
但 Rust 的 `trait` 更安全、更灵活、还能与泛型深度结合。
下面我们来**从直觉 → 语法 → 实战 → 泛型结合 → 高级技巧**系统地讲清楚 Rust 的 `trait` 怎么用。
---
## 🧩 一、Trait 是什么?
一句话解释:
> **Trait 定义了一组类型必须实现的“能力”或“行为”**。
比如“能打印”、“能比较大小”、“能移动”等行为,都可以用 `trait` 定义。
---
## 🧠 二、最简单的 trait 示例
```rust
trait Summary {
fn summarize(&self) -> String;
}
```
上面定义了一个 `Summary` 特征trait它表示“这个类型能生成一个概要字符串”。
任何想拥有这个功能的类型,都要实现它。
---
## 💡 三、为结构体实现 trait
```rust
struct NewsArticle {
title: String,
author: String,
content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{} by {}", self.title, self.author)
}
}
```
现在,`NewsArticle` 类型就有了 `.summarize()` 方法:
```rust
fn main() {
let article = NewsArticle {
title: String::from("Rust trait 学习指南"),
author: String::from("Evan"),
content: String::from("内容..."),
};
println!("{}", article.summarize());
}
```
✅ 输出:
```
Rust trait 学习指南 by Evan
```
---
## 🔧 四、Trait = 行为接口(类比 C++
| 概念 | Rust | C++ 类似 |
| ---- | -------------------------------- | -------------------------------------------- |
| 定义接口 | `trait Summary { ... }` | `class Summary { virtual ... = 0; }` |
| 实现接口 | `impl Summary for NewsArticle` | `class NewsArticle : public Summary { ... }` |
| 调用接口 | `item.summarize()` | `item.summarize()` |
| 多态传参 | `fn notify(item: &impl Summary)` | `void notify(const Summary& item)` |
---
## ⚙️ 五、trait 作为函数参数(多态)
```rust
fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
```
这个函数可以接受**任何实现了 `Summary` 的类型**
```rust
let article = NewsArticle {
title: String::from("Rust 1.80 发布!"),
author: String::from("官方"),
content: String::from("..."),
};
notify(&article);
```
---
## 🔄 六、与泛型结合的写法
等价的更通用写法是:
```rust
fn notify<T: Summary>(item: &T) {
println!("Breaking news! {}", item.summarize());
}
```
这两种写法效果一致:
* `fn foo(x: &impl Trait)`:语法糖
* `fn foo<T: Trait>(x: &T)`:完整泛型写法,可组合多个 trait
---
## 🧩 七、多个 trait 约束
如果希望一个类型实现多个 trait 才能传入:
```rust
fn show<T: Summary + Clone>(item: &T) {
println!("{}", item.summarize());
}
```
或者更清晰的写法:
```rust
fn show<T>(item: &T)
where
T: Summary + Clone,
{
println!("{}", item.summarize());
}
```
---
## 🔁 八、Trait 默认实现
trait 还可以提供**默认方法实现**
```rust
trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
```
实现时可以选择覆盖它:
```rust
impl Summary for NewsArticle {
// 也可以不写 summarize(),直接用默认实现
}
```
---
## 🧩 九、返回实现 trait 的类型impl Trait 返回)
函数也可以**返回实现某个 trait 的类型**
```rust
fn make_article() -> impl Summary {
NewsArticle {
title: String::from("Hello"),
author: String::from("Rust"),
content: String::from("..."),
}
}
```
这里的 `impl Summary` 意思是“返回一个实现了 `Summary` 的对象”,
但不能同时返回多种不同类型(必须一致)。
---
## 💥 十、trait 对象(动态分发)
如果你希望“一个变量”能存放**多种类型但都有共同 trait**,用 `Box<dyn Trait>`
```rust
fn main() {
let article = NewsArticle {
title: String::from("Rust"),
author: String::from("Evan"),
content: String::from("..."),
};
let tweet = Tweet {
username: String::from("rustacean"),
content: String::from("trait 太强了"),
};
let items: Vec<Box<dyn Summary>> = vec![
Box::new(article),
Box::new(tweet),
];
for i in items {
println!("{}", i.summarize());
}
}
```
这就类似于 C++ 的虚函数表vtable动态多态。
---
## 🧩 十一、完整例子trait、泛型、多态一起
```rust
trait Summary {
fn summarize(&self) -> String;
}
struct NewsArticle {
title: String,
author: String,
}
struct Tweet {
username: String,
content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{} by {}", self.title, self.author)
}
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("@{}: {}", self.username, self.content)
}
}
fn notify<T: Summary>(item: &T) {
println!("Breaking news! {}", item.summarize());
}
fn main() {
let tweet = Tweet {
username: String::from("EvanZ"),
content: String::from("Rust trait 学到了!"),
};
let article = NewsArticle {
title: String::from("学习 Rust 的一天"),
author: String::from("Evan"),
};
notify(&tweet);
notify(&article);
}
```
输出:
```
Breaking news! @EvanZ: Rust trait 学到了!
Breaking news! 学习 Rust 的一天 by Evan
```
---
## ✅ 十二、总结表
| 功能 | 语法 | 含义 |
| -------- | ------------------------------------------------ | ---------------- |
| 定义 trait | `trait TraitName { fn func(&self); }` | 定义行为接口 |
| 实现 trait | `impl TraitName for Type { ... }` | 给类型实现行为 |
| 参数约束 | `fn f<T: Trait>(t: &T)``fn f(t: &impl Trait)` | 仅接受实现了 Trait 的类型 |
| 多 trait | `T: TraitA + TraitB` | 同时要求多个行为 |
| 返回 trait | `-> impl Trait` | 返回实现了该行为的类型 |
| 动态多态 | `Box<dyn Trait>` | 在运行时存放不同实现 |
| 默认实现 | `fn func(&self) { ... }` | 允许被覆盖或继承默认功能 |
---
是否希望我接着讲讲 **trait 与泛型的底层机制**(即静态分发 vs 动态分发的区别),包括它们的性能差异与编译原理?(这部分对理解 Rust trait 的“真功夫”非常有帮助)