泛型是Rust实现代码复用的核心机制。通过泛型,你可以编写适用于多种类型的函数、结构体和枚举,而无需为每种类型重复编写代码。Rust的泛型通过单态化(monomorphization)在编译期展开,因此没有运行时开销。
学习目标:掌握泛型函数、泛型结构体、泛型枚举、泛型方法、泛型约束基础
// 不用泛型:为每种类型写一遍
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 largest(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
fn main() {
let numbers = vec![34, 50, 25, 100, 65];
println!("最大数字: {}", largest(&numbers));
let chars = vec!['y', 'm', 'a', 'q'];
println!("最大字符: {}", largest(&chars));
let floats = vec![1.1, 3.3, 2.2, 5.5, 4.4];
println!("最大浮点: {}", largest(&floats));
}
✅ 验证通过
// 泛型结构体
struct Point {
x: T,
y: T,
}
impl Point {
fn new(x: T, y: T) -> Self {
Point { x, y }
}
fn x(&self) -> &T {
&self.x
}
fn y(&self) -> &T {
&self.y
}
}
// 为特定类型实现方法
impl Point {
fn distance_from_origin(&self) -> f64 {
(self.x.powi(2) + self.y.powi(2)).sqrt()
}
}
// 多类型参数
struct Pair {
first: T,
second: U,
}
impl Pair {
fn new(first: T, second: U) -> Self {
Pair { first, second }
}
// 消耗self,返回翻转类型的Pair
fn flip(self) -> Pair {
Pair {
first: self.second,
second: self.first,
}
}
}
fn main() {
let integer_point = Point::new(5, 10);
println!("整数点: ({}, {})", integer_point.x(), integer_point.y());
let float_point = Point::new(3.0, 4.0);
println!("浮点点距离原点: {:.2}", float_point.distance_from_origin());
let pair = Pair::new("hello", 42);
println!("Pair: {} {}", pair.first, pair.second);
let flipped = Pair::new("Rust", 2024).flip();
println!("翻转: {} {}", flipped.first, flipped.second);
}
✅ 验证通过
// 标准库中的泛型枚举
// Option
// Result
// Vec
// HashMap
// 自定义泛型枚举
enum TreeNode {
Leaf(T),
Branch {
value: T,
left: Box<TreeNode,
right: Box<TreeNode,
},
Empty,
}
impl TreeNode {
fn count(&self) -> usize {
match self {
TreeNode::Leaf(_) => 1,
TreeNode::Branch { left, right, .. } => {
1 + left.count() + right.count()
}
TreeNode::Empty => 0,
}
}
fn depth(&self) -> usize {
match self {
TreeNode::Leaf(_) => 1,
TreeNode::Branch { left, right, .. } => {
1 + left.depth().max(right.depth())
}
TreeNode::Empty => 0,
}
}
}
// 有序链表
enum SortedList {
Nil,
Cons { value: T, next: Box<SortedList },
}
impl SortedList {
fn new() -> Self {
SortedList::Nil
}
fn insert(self, value: T) -> Self {
match self {
SortedList::Nil => SortedList::Cons {
value,
next: Box::new(SortedList::Nil),
},
SortedList::Cons { value: head, next } if value < head => {
SortedList::Cons {
value,
next: Box::new(SortedList::Cons {
value: head,
next,
}),
}
}
SortedList::Cons { value: head, next } => SortedList::Cons {
value: head,
next: Box::new(next.insert(value)),
},
}
}
fn to_vec(&self) -> Vec<&T> {
match self {
SortedList::Nil => vec![],
SortedList::Cons { value, next } => {
let mut v = vec![value];
v.extend(next.to_vec());
v
}
}
}
}
fn main() {
// 树
let tree = TreeNode::Branch {
value: 10,
left: Box::new(TreeNode::Leaf(5)),
right: Box::new(TreeNode::Branch {
value: 15,
left: Box::new(TreeNode::Leaf(12)),
right: Box::new(TreeNode::Empty),
}),
};
println!("树节点数: {}", tree.count());
println!("树深度: {}", tree.depth());
// 有序链表
let list = SortedList::new()
.insert(5)
.insert(2)
.insert(8)
.insert(1)
.insert(10);
println!("有序链表: {:?}", list.to_vec());
}
✅ 验证通过
/// 一个简单的键值存储,支持泛型键和值
struct KVStore {
entries: Vec<(K, V)>,
}
impl KVStore {
fn new() -> Self {
KVStore { entries: Vec::new() }
}
fn len(&self) -> usize {
self.entries.len()
}
fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}
impl KVStore {
fn insert(&mut self, key: K, value: V) -> Option {
for entry in &mut self.entries {
if entry.0 == key {
let old = std::mem::replace(&mut entry.1, value);
return Some(old);
}
}
self.entries.push((key, value));
None
}
fn get(&self, key: &K) -> Option<&V> {
self.entries.iter()
.find(|(k, _)| k == key)
.map(|(_, v)| v)
}
fn get_mut(&mut self, key: &K) -> Option<&mut V> {
self.entries.iter_mut()
.find(|(k, _)| k == key)
.map(|(_, v)| v)
}
fn remove(&mut self, key: &K) -> Option {
if let Some(pos) = self.entries.iter().position(|(k, _)| k == key) {
Some(self.entries.remove(pos).1)
} else {
None
}
}
fn contains_key(&self, key: &K) -> bool {
self.entries.iter().any(|(k, _)| k == key)
}
}
impl KVStore {
fn print_all(&self) {
println!("=== KVStore ({}条记录) ===", self.len());
for (k, v) in &self.entries {
println!(" {} => {}", k, v);
}
}
}
fn main() {
// 字符串键值
let mut store = KVStore::new();
store.insert("name", "Rust");
store.insert("version", "1.95");
store.insert("year", "2010");
store.print_all();
// 获取值
if let Some(name) = store.get(&"name") {
println!("\n名称: {}", name);
}
// 更新值
if let Some(old) = store.insert("version", "1.96") {
println!("版本更新: {} → {}", old, store.get(&"version").unwrap());
}
// 整数键
let mut scores: KVStore = KVStore::new();
scores.insert(1, "Alice".to_string());
scores.insert(2, "Bob".to_string());
scores.insert(3, "Charlie".to_string());
println!("\n成绩表:");
for i in 1..=3 {
if let Some(name) = scores.get(&i) {
println!(" #{}: {}", i, name);
}
}
// 删除
let removed = scores.remove(&2);
println!("\n删除#2: {:?}", removed);
println!("剩余: {}条", scores.len());
}
✅ 验证通过
实现Stack<T>,使用Vec<T>作为底层存储,支持push、pop、peek、is_empty、len。
实现swap<T>(pair: (T, T)) -> (T, T)和first<T, U>(pair: (T, U)) -> T。
实现Matrix<T>,支持加法(要求T: Add)、标量乘法、转置。
🔒 下一课解锁:trait与trait bound —— Rust的抽象机制
use std::fmt::Display;
// 泛型函数组合
fn compose(f: F, g: G) -> impl Fn(A) -> C
where F: Fn(A) -> B, G: Fn(B) -> C {
move |x| g(f(x))
}
// 泛型验证
fn validate(value: T, checkers: &[Box Result<(), E>>]) -> Result
where E: Clone {
for checker in checkers {
checker(&value)?;
}
Ok(value)
}
fn main() {
// 函数组合
let double = |x: i32| x * 2;
let add_one = |x: i32| x + 1;
let double_then_add = compose(double, add_one);
println!("compose(5): {}", double_then_add(5)); // 11
let to_string = |x: i32| x.to_string();
let add_hello = |s: String| format!("Hello, {}!", s);
let greet_number = compose(to_string, add_hello);
println!("{}", greet_number(42));
// 泛型验证器
let age_checkers: Vec Result<(), String>>> = vec![
Box::new(|age| if *age < 0 { Err("年龄不能为负".into()) } else { Ok(()) }),
Box::new(|age| if *age > 150 { Err("年龄不合理".into()) } else { Ok(()) }),
];
match validate(25, &age_checkers) {
Ok(age) => println!("年龄 {} 有效", age),
Err(e) => println!("验证失败: {}", e),
}
match validate(-5, &age_checkers) {
Ok(_) => println!("有效"),
Err(e) => println!("❌ {}", e),
}
}
✅ 验证通过
use std::fmt::Display;
// 泛型排序
fn bubble_sort(arr: &mut [T]) {
let n = arr.len();
for i in 0..n {
for j in 0..n - 1 - i {
if arr[j] > arr[j + 1] {
arr.swap(j, j + 1);
}
}
}
}
// 泛型二分查找
fn binary_search(arr: &[T], target: &T) -> Option {
let mut left = 0;
let mut right = arr.len();
while left < right {
let mid = left + (right - left) / 2;
if &arr[mid] == target { return Some(mid); }
else if &arr[mid] < target { left = mid + 1; }
else { right = mid; }
}
None
}
// 泛型统计
fn stats>(data: &[T]) -> (f64, f64, f64) {
let sum: f64 = data.iter().map(|&x| x.into()).sum();
let mean = sum / data.len() as f64;
let variance = data.iter().map(|&x| (x.into() - mean).powi(2)).sum::() / data.len() as f64;
(mean, variance.sqrt(), sum)
}
fn main() {
let mut nums = vec![5, 2, 8, 1, 9, 3, 7, 4, 6];
bubble_sort(&mut nums);
println!("排序: {:?}", nums);
println!("查找7: {:?}", binary_search(&nums, &7));
let mut floats = vec![3.14, 2.71, 1.41, 1.73, 2.24];
bubble_sort(&mut floats);
println!("浮点排序: {:?}", floats);
let data = vec![10, 20, 30, 40, 50];
let (mean, stddev, sum) = stats(&data);
println!("均值={:.1} 标准差={:.1} 总和={:.0}", mean, stddev, sum);
}
✅ 验证通过