核心知识点
-
泛型(Generics)
- 编写可用于多种类型的代码(函数、结构体、枚举)
- 示例:
Option<T>,Result<T, E>本身就是泛型类型
-
Trait
- 定义共享行为(类似接口)
- 通过
impl Trait for Type实现行为 - 常见 Trait:
Debug,Clone,Display,Iterator
-
Trait Bound
- 限制泛型类型必须实现某些 Trait
- 语法:
fn f<T: TraitA + TraitB>(x: T) { ... }
-
生命周期 + 泛型组合使用
- 标注泛型数据的生命周期
学习步骤
1. 泛型函数与结构体
// 泛型函数:返回两个值中较大的那个
fn largest<T: PartialOrd>(a: T, b: T) -> T {
if a > b { a } else { b }
}
// 泛型结构体
struct Point<T> {
x: T,
y: T,
}
fn main() {
let p1 = Point { x: 5, y: 10 }; // Point<i32>
let p2 = Point { x: 1.0, y: 4.0 }; // Point<f64>
}
2. 定义并实现 Trait
// 定义 Trait
pub trait Summary {
fn summarize(&self) -> String;
}
// 为结构体实现 Trait
struct NewsArticle {
headline: String,
content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("标题: {}", self.headline)
}
}
3. Trait Bound 的使用
// 使用 Trait Bound 约束泛型
fn notify<T: Summary>(item: &T) {
println!("新通知: {}", item.summarize());
}
// 简化写法:`impl Trait` 语法
fn get_summarizable() -> impl Summary {
NewsArticle { /* ... */ }
}
练习题
题目1:泛型最大值函数
// 实现函数 largest,返回切片中的最大值
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
fn main() {
let numbers = vec![34, 50, 25, 100, 65];
println!("最大数字: {}", largest(&numbers));
let chars = vec!['y', 'm', 'a', 'q'];
println!("最大字符: {}", largest(&chars));
}
题目2:为 Point 实现 Display
use std::fmt;
struct Point<T> {
x: T,
y: T,
}
// 为所有 Point<T> 实现 Display
impl<T: fmt::Display> fmt::Display for Point<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
fn main() {
let p = Point { x: 5, y: 10 };
println!("坐标: {}", p); // 输出 (5, 10)
}
题目3:自定义 Drawable Trait
// 定义 Trait
trait Drawable {
fn draw(&self);
}
// 实现结构体
struct Circle { radius: f64 }
struct Square { side: f64 }
impl Drawable for Circle {
fn draw(&self) {
println!("绘制圆形,半径: {}", self.radius);
}
}
impl Drawable for Square {
fn draw(&self) {
println!("绘制正方形,边长: {}", self.side);
}
}
// 接受实现 Drawable 的泛型函数
fn render<T: Drawable>(item: &T) {
item.draw();
}
fn main() {
let circle = Circle { radius: 3.0 };
let square = Square { side: 2.5 };
render(&circle); // 输出:绘制圆形,半径: 3
render(&square); // 输出:绘制正方形,边长: 2.5
}
关键技巧
-
derive自动实现 Trait- 使用
#[derive(Debug, Clone)]让编译器自动生成常见 Trait 的实现
#[derive(Debug, PartialEq)] struct Data { value: i32, } - 使用
-
Trait 的默认实现
- 在 Trait 定义中提供默认方法:
trait Summary { fn summarize(&self) -> String { String::from("(阅读更多...)") } } -
使用
where简化复杂 Trait Boundfn some_func<T, U>(t: &T, u: &U) -> i32 where T: Display + Clone, U: Debug + PartialEq, { // ... }
常见错误
错误:T doesn't implement a trait
fn print_debug<T>(value: T) {
println!("{:?}", value); // 错误!T 未实现 Debug
}
- 修复:添加 Trait Bound
fn print_debug<T: Debug>(value: T) { ... }
下一步任务
- 完成练习题,尝试为你的自定义结构体实现
IteratorTrait - 阅读《Rust 程序设计语言》第10章
- 探索标准库中的常见 Trait(如
From,Into,Drop)