Skip to content

什么是泛型

可以使用泛型为像函数签名或结构体这样的项创建定义, 这样它们就可以用于多种不同的具体数据类型

简单来说就是: 在(函数/结构/枚举等)定义时不确定数据类型, 在调用的时候才确定数据类型

为什么要使用泛型: 可以高度重用代码, 而且不会损失性能

在函数定义中使用泛型

泛型可以有很多个, 但先从简单的开始, 先体验一个泛型

rust
// largest_i32 和 lagest_char 实现逻辑都是一样的,
// 唯一不同的就是参数和返回值的数据类型不同

fn largest_i32(list: &[i32]) -> &i32 {
    let mut largest = &list[0];

    for item in list {
        if item > largest {
            largest = item;
        }
    }

    largest
}

fn largest_char(list: &[char]) -> &char {
    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_i32(&number_list);
    println!("The largest number is {result}");

    let char_list = vec!['y', 'm', 'a', 'q'];
    let result = largest_char(&char_list);
    println!("The largest char is {result}");
}
rust
use std::cmp::PartialOrd;
// PartialOrd 是一个让值可以比较大小的 Trait (类似接口)
// T:PartialOrd 表示传入的类型必须是可以被比较大小的

// 两个函数变为一个函数, 仅仅是修改了类型,提高代码重用率
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 Rect<T, R> {
    width: T,
    height: R,
}

fn main() {
    // 要不然就全部手动传入
    let r1: Rect<f32, u32> = Rect {
        width: 2.2,
        height: 3
    };
    println!("r1 width: {}", r1.width);
    println!("r1 height: {}", r1.height);

    // 要不然就全部自动推导, 不能只手动指定一个
    let r2 = Rect {
        width: 3.2,
        height: 4.5
    };
    println!("r2 width: {}", r2.width);
    println!("r2 height: {}", r2.height);
}

枚举定义中的泛型

系统定义的 OptionResult 就是使用的泛型

rust
pub enum Option<T> {
    None,
    Some(T),
}
rust
pub enum Result<T, E> {
    Ok(T),
    Err(E),
}

方法定义中的泛型

rust
struct Rect<T, R> {
    width: T,
    height: R,
}

impl<T, R> Rect<T, R> {
    fn new(width: T, height: R) -> Rect<T, R> {
        Rect {
            width,
            height,
        }
    }
}

fn main() {
    let r1 = Rect::new(2.2, 3);
    println!("r1 width: {}", r1.width);
    println!("r1 height: {}", r1.height);
}

Released under the MIT License.