泛型
约 626 字大约 2 分钟
2025-09-26
所谓泛型就是把 类型当做参数的抽象机制,让函数、结构体、枚举等能以占位类型工作,通常表示为 <T>。在调用或实例化时再填入具体类型
提示
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 char_list = vec!['y', 'm', 'a', 'q'];
let number_result = largest(&number_list);
let char_result = largest(&char_list);
println!("The largest number is {number_result}");
println!("The largest char is {char_result}")
}注
在上述案例中,需要给 T 额外去限定类型的范围,这是因为在 Rust 中 >、<、>=、<= 这些比较运算符并不是对所有类型都可用的。只有实现了 PartialOrd 这个 trait 的类型才能进行大小比较。但对泛型参数 T 来说,编译器默认不知道它是否 "可比较"。因此需要额外声明式的进行限定
结构体中的泛型
结构体中定义泛型与函数参数类似,在结构体名称后声明泛型
结构体中的泛型
#[derive(Debug)]
struct Point<T, U> {
x: T,
y: U
}
fn main() {
let point = Point { x: 5, y: 4.0 };
println!(
"Point x is: {:#?}, y is: {:#?}",
point.x, point.y
);
}枚举中的泛型
枚举的泛型与结构体就更类似了,例如 Option<T> 与 Result<T>
Option<T> 的实现enum Option<T> {
Some(T),
None,
}Result<T> 的实现enum Result<T, E> {
Ok(T),
Err(E),
}方法中的泛型
为结构体和枚举实例实现方法时,同样可以使用泛型
重要
方法中的泛型需要在 impl 后声明泛型参数,通过在 impl 后声明泛型,Rust 就知道结构中的类型是泛型而不是具体的类型,后续在结构体的方法中就可以继续使用泛型了
方法中的泛型
#[derive(Debug)]
struct Point<T, U> {
x: T,
y: U,
}
impl<T, U> Point<T, U> {
fn x(&self) -> &T {
&self.x
}
fn y(&self) -> &U {
&self.y
}
}
fn main() {
let p = Point { x: 5, y: 10 };
println!("p.x = {}", p.x());
println!("p.y = {}", p.y());
}