Learn
Rust/13-generics

泛型

泛型(generics) 让你写出不依赖具体类型、又能保持类型安全的代码,避免为 i32/f64/String 各写一份逻辑。

1. 泛型函数

泛型函数
fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
    let mut max = list[0];
    for &item in list {
        if item > max {
            max = item;
        }
    }
    max
}
 
fn main() {
    let a = largest(&[1, 5, 3]);      // T = i32
    let b = largest(&[1.0, 2.5]);     // T = f64
    println!("{} {}", a, b);
    println!("{}", largest(&['a', 'z', 'm']));   // T = char
}
ℹ️trait bound 限制能力

T: PartialOrd 表示 T 必须可比较(才能用 >);+ Copy 表示可复制(避免所有权移动)。泛型不会凭空获得操作能力。

2. 泛型结构体与枚举

泛型结构体
struct Point<T> {
    x: T,
    y: T,
}
 
// 需要不同类型时用两个参数
struct Pair<T, U> {
    first: T,
    second: U,
}
 
fn main() {
    let int_point = Point { x: 5, y: 10 };
    let float_point = Point { x: 1.5, y: 2.5 };
    println!("整数点 ({}, {})", int_point.x, int_point.y);
    println!("浮点点 ({}, {})", float_point.x, float_point.y);
 
    let p = Pair { first: 1, second: String::from("one") };
    println!("{} -> {}", p.first, p.second);
}

标准库的 Option 与 Result 正是泛型枚举:

enum Result<T, E> {
    Ok(T),
    Err(E),
}
⚠️单类型参数要求同类型

上面的 Point<T> 要求 x 与 y 同类型。若需不同,用两个参数 Point<T, U>。

3. 单态化(monomorphization)

Rust 在编译期为用到的每个具体类型生成专属代码:

let _ = largest(&[1, 2]);
let _ = largest(&[1.0, 2.0]);

编译器实际生成 largest_i32 与 largest_f64 两份函数。这就是「零成本抽象」——运行时没有泛型开销,性能等同手写专版。

💡零成本的意义

泛型不引入任何运行时间接层或额外内存。代价是二进制体积略增(每种类型一份代码),但速度是原生的。

4. trait bound 的两种写法

// 1. 在函数签名里
fn f<T: Display + Clone>(x: T) {}
 
// 2. where 子句,更清晰
fn f<T>(x: T)
where
    T: Display + Clone,
{
}

5. 默认类型参数

enum Result<T, E = std::io::Error> {
    Ok(T),
    Err(E),
}
🎯练习

实现一个泛型 struct Pair<T> { first: T, second: T },加一个方法 fn cmp(&self) -> ...(提示:约束 T: PartialOrd)返回较大者。再写个 where 子句版本的打印函数。

小结

  • 泛型提升复用而不牺牲类型安全
  • T: Trait 约束类型能做什么(如比较、复制)
  • 单态化:编译期为各具体类型生成专属代码,零运行时开销
  • where 子句让复杂 bound 更易读
  • 下一章看 trait —— Rust 的抽象核心 →