豹子头 (雷豹)

我这双手,不光能抓人,还能抓鸡、抓鸭...只要是“能抓的东西” (Trait),我都抓给你看!

包龙星

这就是泛型 (Generics)!你不必专门学“抓人手”或“抓鸡手”,只要学一套“万能抓手”就行了。

Rust 泛型与特性:万能武功

泛型 (Generics) 让我们可以编写适用于多种类型的代码。特性 (Traits) 定义了类型必须具有的功能(类似于接口)。

🧬 泛型函数

使用 <T> 来代表任意类型。

// 这个函数可以打印任何实现了 Display trait 的类型
use std::fmt::Display;

fn print_it<T: Display>(item: T) {
    println!("打印内容: {}", item);
}

fn main() {
    print_it(100);       // i32
    print_it("Hello");   // &str
}

📜 定义 Trait (特性)

Trait 告诉编译器:这个类型能做什么。

// 定义一个“吵架”特性
trait Quarrel {
    fn shout(&self) -> String;
}

struct Official {
    name: String,
}

// 为 Official 实现 Quarrel
impl Quarrel for Official {
    fn shout(&self) -> String {
        format!("{}:凭什么抓我!", self.name)
    }
}

🔗 Trait Bound (特性约束)

我们可以限制泛型必须实现某些 Trait。

fn battle<T: Quarrel>(fighter: T) {
    println!("战斗开始: {}", fighter.shout());
}

🎁 where 子句

当约束太长时,用 where 会更清晰。

fn some_function<T, U>(t: T, u: U) -> i32
    where T: Display + Clone,
          U: Clone + Debug
{
    // ...
    0
}
🥋

动手时刻:全能武者

编写一个泛型函数。

  1. 定义一个 Trait Weapon,包含方法 attack(&self)
  2. 定义两个结构体 Sword (剑) 和 Knife (刀),并为它们实现 Weapon
  3. 编写一个泛型函数 use_weapon<T: Weapon>(w: T),在里面调用 attack
  4. 在 main 中分别传入剑和刀进行测试。
查看参考答案 (点击揭榜)

trait Weapon {
    fn attack(&self);
}

struct Sword;
struct Knife;

impl Weapon for Sword {
    fn attack(&self) {
        println!("唰!剑气纵横!");
    }
}

impl Weapon for Knife {
    fn attack(&self) {
        println!("噗!手起刀落!");
    }
}

fn use_weapon<T: Weapon>(w: T) {
    w.attack();
}

fn main() {
    let s = Sword;
    let k = Knife;
    
    use_weapon(s);
    use_weapon(k);
}
                    

成就解锁:【武林盟主】 ⚔️