Rust 的泛型(Generics)允许编写可复用的代码,通过抽象类型或行为来避免重复逻辑。
1. 泛型的基本使用
函数泛型
在函数中定义泛型参数,支持不同类型的数据操作:
fn max<T: PartialOrd>(a: T, b: T) -> T {
if a > b { a } else { b }
}
fn main() {
let largest_number = max(3, 5);
println!("The largest number is {}", largest_number);
let largest_string = max("apple", "banana");
println!("The largest string is {}", largest_string);
}
在这个例子中,max 函数使用了泛型参数 T,并且指定了 T 必须实现 PartialOrd trait,这样才能使用大于操作符 >。
结构体泛型
结构体的字段可以使用泛型类型:
struct Point<T> {
x: T,
y: T,
}
fn main() {
let integer_point = Point { x: 5, y: 10 };
let float_point = Point { x: 1.2, y: 4.5 };
println!("Integer point: ({}, {})", integer_point.x, integer_point.y);
println!("Float point: ({}, {})", float_point.x, float_point.y);
}
枚举泛型
Rust 标准库中的 Option<T>
和 Result<T, E>
是经典的泛型枚举:
enum Option<T> {
Some(T),
None,
}
enum Result<T, E> {
Ok(T),
Err(E),
}
2.方法中的泛型
为泛型结构体实现方法:
impl<T> Point<T> {
fn new(x: T, y: T) -> Self {
Point { x, y }
}
}
// 为特定类型实现方法(如 f32)
impl Point<f32> {
fn distance_from_origin(&self) -> f32 {
(self.x.powi(2) + self.y.powi(2)).sqrt()
}
}
3.常见应用场景
集合类型(如 Vec<T>、HashMap<K, V>)。
错误处理(Result<T, E>)。
函数式编程(闭包、迭代器适配器)。
多态 API(如 Web 框架的路由处理)。
4.注意事项
避免过度泛型化:仅在需要抽象不同类型时使用泛型。
命名规范:通常使用 T、U、K、V 等单字母命名泛型参数。
结合 Trait 使用:通过 Trait 约束明确泛型的行为(后面详讲)。
5.改写栈
struct MyStack<T> {
queue: Vec<T>,
}
impl <T> MyStack<T> {
fn new() -> Self {
return MyStack {
queue: Vec::new()
};
}
fn push(&mut self, x: T) {
self.queue.push(x);
}
fn pop(&mut self) -> T {
self.queue.pop().expect("Stack is empty")
}
fn top(&self) -> &T {
self.queue.last().expect("Stack is empty")
}
fn empty(&self) -> bool {
return self.queue.is_empty();
}
}
fn main() {
let mut num: MyStack<i32> = MyStack::new();
num.push(5);
num.push(6);
let ret_1: i32 = num.pop();
println!("{}", ret_1);
let ret_2: i32 = num.pop();
println!("{}", ret_2);
let mut s1: MyStack<String> = MyStack::new();
s1.push(String::from("rust"));
s1.push(String::from("python"));
let ret_3 = s1.pop();
println!("{}", ret_3);
let ret_4 = s1.pop();
println!("{}", ret_4);
}
top返回是引用&T,如果一定要返回T,需用Clone克隆
fn top(&mut self) -> T
where
T: Clone, // 添加 Clone 约束
{
let n = self.pop();
let cloned = n.clone();
self.push(n);
cloned
}
总结
泛型是编写灵活且可重用代码的强大工具。它们使得你可以编写适用于多种类型的代码,而不需要重复自己。Rust 的泛型系统不仅强大而且非常高效,因为所有泛型代码都在编译时被具体化,确保运行时性能不会受到影响。通过合理地使用泛型,你可以创建出更加通用、类型安全的程序。