🦀 第09课:泛型

泛型是Rust实现代码复用的核心机制。通过泛型,你可以编写适用于多种类型的函数、结构体和枚举,而无需为每种类型重复编写代码。Rust的泛型通过单态化(monomorphization)在编译期展开,因此没有运行时开销。

核心特性 第9/25课

学习目标:掌握泛型函数、泛型结构体、泛型枚举、泛型方法、泛型约束基础

🔧 泛型函数

// 不用泛型:为每种类型写一遍
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));
}
最大数字: 100 最大字符: y 最大浮点: 5.5

✅ 验证通过

📦 泛型结构体

// 泛型结构体
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);
}
整数点: (5, 10) 浮点点距离原点: 5.00 Pair: hello 42 翻转: 2024 Rust

✅ 验证通过

🎯 泛型枚举

// 标准库中的泛型枚举
// 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());
}
树节点数: 4 树深度: 3 有序链表: [1, 2, 5, 8, 10]

✅ 验证通过

🏗️ 综合实战:泛型容器

/// 一个简单的键值存储,支持泛型键和值
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());
}
=== KVStore (3条记录) === name => Rust version => 1.95 year => 2010 名称: Rust 版本更新: 1.95 → 1.96 成绩表: #1: Alice #2: Bob #3: Charlie 删除#2: Some("Bob") 剩余: 2条

✅ 验证通过

📝 练习

练习1:泛型栈

实现Stack<T>,使用Vec<T>作为底层存储,支持push、pop、peek、is_empty、len。

练习2:泛型元组工具

实现swap<T>(pair: (T, T)) -> (T, T)first<T, U>(pair: (T, U)) -> T

练习3:泛型矩阵

实现Matrix<T>,支持加法(要求T: Add)、标量乘法、转置。

🏆 本课成就

🔒 下一课解锁:trait与trait bound —— Rust的抽象机制

🔧 泛型与trait bound实战

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),
    }
}
compose(5): 11 Hello, 42! 年龄 25 有效 ❌ 年龄不能为负

✅ 验证通过

🏗️ 泛型算法实战

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);
}
排序: [1, 2, 3, 4, 5, 6, 7, 8, 9] 查找7: Some(6) 浮点排序: [1.41, 1.73, 2.24, 2.71, 3.14] 均值=30.0 标准差=14.1 总和=150

✅ 验证通过