万能模板:泛型

原理

Rust 泛型通过**单态化(Monomorphization)**实现:编译器为每个被使用的具体类型生成独立的代码副本。fn foo<T>() 被调用为 foo::<i32>()foo::<f64>() 时,生成两个独立的函数实例。

这是零成本抽象(zero-cost abstraction):运行时性能和手写具体类型版本完全一致,因没有虚函数表查找和 Box 装箱。代价是编译时间增加(更多代码需要 LLVM 优化)和二进制体积变大(代码膨胀)。

对比 C++ 模板:C++ 模板是图灵完备的宏展开,Rust 泛型先做类型检查再单态化,错误信息更清晰。约束通过 trait bound(T: PartialOrd)限制可用的操作。

宏对比
C++: 模板


语法

泛型函数

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第二、三类型
KHashMap 键
VHashMap 值
E错误类型

实践

力扣问题

力扣: 力扣排序题 — 泛型排序函数

fn sort_slice<T: Ord>(slice: &mut [T]) {
    slice.sort();
}

AI 自检

  1. 单态化如何导致二进制体积膨胀?size 和性能的权衡是什么?
  2. impl<T> Point<T>impl<T> 的作用域?为什么编译器需要这个声明?