泛型
学习目标
- 理解泛型的作用
- 掌握结构体、枚举、函数的泛型
- 理解单态化
- 掌握泛型与 trait 的结合
核心概念
为什么需要泛型
// 没有泛型:为每种类型写一遍
fn max_i32(a: i32, b: i32) -> i32 { if a > b { a } else { b } }
fn max_f64(a: f64, b: f64) -> f64 { if a > b { a } else { b } }
// 有泛型:一个函数搞定
fn max<T: PartialOrd>(a: T, b: T) -> T {
if a > b { a } else { b }
}
函数泛型
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in &list[1..] {
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));
}
结构体泛型
struct Point<T> {
x: T,
y: T,
}
// 不同类型的泛型
struct Point2<T, U> {
x: T,
y: U,
}
impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
}
impl Point<f64> {
fn distance_from_origin(&self) -> f64 {
(self.x.powi(2) + self.y.powi(2)).sqrt()
}
}
fn main() {
let integer_point = Point { x: 5, y: 10 };
let float_point = Point { x: 1.0, y: 4.0 };
println!("距离: {}", float_point.distance_from_origin());
}
枚举泛型
// 标准库的 Option 和 Result 就是泛型枚举
enum Option<T> {
Some(T),
None,
}
enum Result<T, E> {
Ok(T),
Err(E),
}
// 自定义泛型枚举
enum Either<L, R> {
Left(L),
Right(R),
}
impl<L, R> Either<L, R> {
fn is_left(&self) -> bool {
matches!(self, Either::Left(_))
}
fn unwrap_left(self) -> L {
match self {
Either::Left(l) => l,
Either::Right(_) => panic!("called unwrap_left on Right"),
}
}
}
单态化
// 编译器会为每个使用的具体类型生成独立代码
fn add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
a + b
}
fn main() {
let x = add(1, 2); // 编译器生成 add_i32
let y = add(1.0, 2.0); // 编译器生成 add_f64
// 运行时零开销
}
实践练习
练习 1:泛型栈
struct Stack<T> {
elements: Vec<T>,
}
impl<T> Stack<T> {
fn new() -> Self {
Stack { elements: Vec::new() }
}
fn push(&mut self, item: T) {
self.elements.push(item);
}
fn pop(&mut self) -> Option<T> {
self.elements.pop()
}
fn peek(&self) -> Option<&T> {
self.elements.last()
}
fn is_empty(&self) -> bool {
self.elements.is_empty()
}
}
fn main() {
let mut stack = Stack::new();
stack.push(1);
stack.push(2);
println!("{:?}", stack.pop());
}
练习 2:泛型 Pair
struct Pair<T> {
first: T,
second: T,
}
impl<T> Pair<T> {
fn new(first: T, second: T) -> Self {
Pair { first, second }
}
}
impl<T: PartialOrd> Pair<T> {
fn larger(&self) -> &T {
if self.first >= self.second {
&self.first
} else {
&self.second
}
}
}
fn main() {
let pair = Pair::new(10, 20);
println!("较大的: {}", pair.larger());
}
常见错误
1. 缺少 trait bound
// ❌ T 可能不支持 >
fn max<T>(a: T, b: T) -> T {
if a > b { a } else { b }
}
// ✅ 添加约束
fn max<T: PartialOrd>(a: T, b: T) -> T {
if a > b { a } else { b }
}
2. 泛型参数过多
// ⚠️ 过度泛型化
struct Data<T1, T2, T3, T4, T5> { }
// 考虑用 trait 对象或具体类型
小结
| 用法 | 语法 |
|---|---|
| 函数泛型 | fn f<T>(x: T) |
| 结构体泛型 | struct S<T> { } |
| 枚举泛型 | enum E<T> { } |
| impl 泛型 | impl<T> S<T> { } |
| 单态化 | 编译时生成具体类型代码,零运行时开销 |
练习编辑器
rust
Loading...