万能模板:泛型
原理
Rust 泛型通过**单态化(Monomorphization)**实现:编译器为每个被使用的具体类型生成独立的代码副本。fn foo<T>() 被调用为 foo::<i32>() 和 foo::<f64>() 时,生成两个独立的函数实例。
这是零成本抽象(zero-cost abstraction):运行时性能和手写具体类型版本完全一致,因没有虚函数表查找和 Box 装箱。代价是编译时间增加(更多代码需要 LLVM 优化)和二进制体积变大(代码膨胀)。
对比 C++ 模板:C++ 模板是图灵完备的宏展开,Rust 泛型先做类型检查再单态化,错误信息更清晰。约束通过 trait bound(T: PartialOrd)限制可用的操作。
语法
泛型函数
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut max = &list[0];
for item in list {
if item > max { max = item; }
}
max
}泛型结构体
struct Point<T> { x: T, y: T }
struct Pair<T, U> { first: T, second: U }泛型方法
impl<T> Point<T> {
fn x(&self) -> &T { &self.x }
}
// 针对特定类型实现
impl Point<f64> {
fn distance(&self) -> f64 {
(self.x.powi(2) + self.y.powi(2)).sqrt()
}
}泛型枚举(标准库实例)
enum Option<T> { Some(T), None }
enum Result<T, E> { Ok(T), Err(E) }Trait Bound 三种写法
// 1. impl Trait 语法糖
fn f(x: &impl Display) { }
// 2. Turbofish 风格
fn f<T: Display>(x: &T) { }
// 3. where 从句(约束多时推荐)
fn f<T>(x: &T) where T: Display + Clone { }多重约束
fn compare<T: PartialOrd + Display>(a: T, b: T) {
if a > b { println!("{} > {}", a, b); }
}选择
| 命名 | 惯例用法 |
|---|---|
T | 任意类型 |
U, V | 第二、三类型 |
K | HashMap 键 |
V | HashMap 值 |
E | 错误类型 |
实践
力扣问题
力扣: 力扣排序题 — 泛型排序函数
fn sort_slice<T: Ord>(slice: &mut [T]) {
slice.sort();
}AI 自检
- 单态化如何导致二进制体积膨胀?
size和性能的权衡是什么? impl<T> Point<T>中impl<T>的作用域?为什么编译器需要这个声明?