Skip to content

Rust 泛型

泛型是 Rust 中用于编写可重用代码的机制,它允许我们编写适用于多种类型的代码。本章节将介绍 Rust 中的泛型系统。

泛型函数

使用泛型参数定义泛型函数:

rust
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 number_list = vec![34, 50, 25, 100, 65];
    let result = largest(&number_list);
    println!("The largest number is {}", result);
    
    let char_list = vec!['y', 'm', 'a', 'q'];
    let result = largest(&char_list);
    println!("The largest char is {}", result);
}

泛型结构体

定义泛型结构体:

rust
struct Point<T> {
    x: T,
    y: T,
}

impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }
}

impl Point<f32> {
    fn distance_from_origin(&self) -> f32 {
        (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!("integer_point.x = {}", integer_point.x());
    println!("float_point distance = {}", float_point.distance_from_origin());
}

泛型枚举

定义泛型枚举:

rust
enum Option<T> {
    Some(T),
    None,
}

enum Result<T, E> {
    Ok(T),
    Err(E),
}

fn main() {
    let some_number = Some(5);
    let some_string = Some("Hello");
    let absent_number: Option<i32> = None;
    
    println!("some_number: {:?}", some_number);
    println!("some_string: {:?}", some_string);
    println!("absent_number: {:?}", absent_number);
}

泛型方法

定义泛型方法:

rust
struct Point<T, U> {
    x: T,
    y: U,
}

impl<T, U> Point<T, U> {
    fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
        Point {
            x: self.x,
            y: other.y,
        }
    }
}

fn main() {
    let p1 = Point { x: 5, y: 10.4 };
    let p2 = Point { x: "Hello", y: 'c' };
    
    let p3 = p1.mixup(p2);
    println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
}

泛型约束

使用 Trait 约束来限制泛型类型:

rust
use std::fmt::Display;

fn print<T: Display>(item: T) {
    println!("{}", item);
}

fn compare<T: PartialOrd + Copy>(a: T, b: T) -> T {
    if a > b {
        a
    } else {
        b
    }
}

fn main() {
    print(5);
    print(3.14);
    print("Hello");
    
    println!("Larger of 5 and 10: {}", compare(5, 10));
    println!("Larger of 3.14 and 2.71: {}", compare(3.14, 2.71));
}

多重约束

使用 + 符号指定多个约束:

rust
use std::fmt::{Display, Debug};

fn print_item<T: Display + Debug>(item: T) {
    println!("Display: {}", item);
    println!("Debug: {:?}", item);
}

fn main() {
    print_item(5);
    print_item("Hello");
}

where 子句

使用 where 子句可以使复杂的约束更清晰:

rust
use std::fmt::{Display, Debug};

fn print_item<T>(item: T) where T: Display + Debug {
    println!("Display: {}", item);
    println!("Debug: {:?}", item);
}

fn main() {
    print_item(5);
    print_item("Hello");
}

泛型的性能

Rust 的泛型是零成本抽象,编译器会为每个具体类型生成专门的代码,不会带来运行时开销:

rust
fn main() {
    // 编译器会为 i32 生成专门的代码
    let result1 = compare(5, 10);
    // 编译器会为 f64 生成专门的代码
    let result2 = compare(3.14, 2.71);
}

fn compare<T: PartialOrd + Copy>(a: T, b: T) -> T {
    if a > b {
        a
    } else {
        b
    }
}

总结

  • 泛型函数:使用泛型参数定义适用于多种类型的函数
  • 泛型结构体:定义可以存储不同类型值的结构体
  • 泛型枚举:定义可以包含不同类型值的枚举
  • 泛型方法:在结构体或枚举上定义泛型方法
  • 泛型约束:使用 Trait 约束来限制泛型类型
  • 多重约束:使用 + 符号指定多个约束
  • where 子句:使复杂的约束更清晰
  • 零成本抽象:泛型不会带来运行时开销

泛型是 Rust 中编写可重用代码的重要机制。通过本章节的学习,你应该已经掌握了 Rust 中的泛型系统的基本概念和使用方法。