Skip to content

Rust Trait

Trait 是 Rust 中用于定义共享行为的机制,类似于其他语言中的接口。本章节将介绍 Rust 中的 Trait 系统。

Trait 定义

使用 trait 关键字定义 Trait:

rust
trait Animal {
    fn name(&self) -> &str;
    fn speak(&self);
    
    // 默认实现
    fn eat(&self) {
        println!("{} is eating", self.name());
    }
}

实现 Trait

为类型实现 Trait:

rust
trait Animal {
    fn name(&self) -> &str;
    fn speak(&self);
    
    fn eat(&self) {
        println!("{} is eating", self.name());
    }
}

struct Dog {
    name: String,
}

impl Animal for Dog {
    fn name(&self) -> &str {
        &self.name
    }
    
    fn speak(&self) {
        println!("{} says woof!");
    }
}

struct Cat {
    name: String,
}

impl Animal for Cat {
    fn name(&self) -> &str {
        &self.name
    }
    
    fn speak(&self) {
        println!("{} says meow!");
    }
}

fn main() {
    let dog = Dog { name: String::from("Rex") };
    let cat = Cat { name: String::from("Whiskers") };
    
    dog.speak();
    dog.eat();
    
    cat.speak();
    cat.eat();
}

Trait 作为参数

可以将 Trait 作为函数参数,实现多态:

rust
trait Animal {
    fn name(&self) -> &str;
    fn speak(&self);
}

struct Dog {
    name: String,
}

impl Animal for Dog {
    fn name(&self) -> &str {
        &self.name
    }
    
    fn speak(&self) {
        println!("{} says woof!");
    }
}

struct Cat {
    name: String,
}

impl Animal for Cat {
    fn name(&self) -> &str {
        &self.name
    }
    
    fn speak(&self) {
        println!("{} says meow!");
    }
}

fn animal_speak(animal: &impl Animal) {
    animal.speak();
}

fn main() {
    let dog = Dog { name: String::from("Rex") };
    let cat = Cat { name: String::from("Whiskers") };
    
    animal_speak(&dog);
    animal_speak(&cat);
}

Trait 约束

使用 Trait 约束来指定泛型类型必须实现某个 Trait:

rust
trait Animal {
    fn name(&self) -> &str;
}

fn animal_name<T: Animal>(animal: &T) {
    println!("Animal name: {}", animal.name());
}

// 多个 Trait 约束
fn animal_info<T: Animal + std::fmt::Debug>(animal: &T) {
    println!("Animal: {:?}, name: {}", animal, animal.name());
}

// 使用 where 子句
fn animal_details<T>(animal: &T) where T: Animal + std::fmt::Debug {
    println!("Animal details: {:?}, name: {}", animal, animal.name());
}

struct Dog {
    name: String,
}

impl Animal for Dog {
    fn name(&self) -> &str {
        &self.name
    }
}

impl std::fmt::Debug for Dog {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Dog {{ name: '{}' }}", self.name)
    }
}

fn main() {
    let dog = Dog { name: String::from("Rex") };
    animal_name(&dog);
    animal_info(&dog);
    animal_details(&dog);
}

Trait 作为返回类型

可以将 Trait 作为函数返回类型:

rust
trait Animal {
    fn speak(&self);
}

struct Dog;

impl Animal for Dog {
    fn speak(&self) {
        println!("Woof!");
    }
}

struct Cat;

impl Animal for Cat {
    fn speak(&self) {
        println!("Meow!");
    }
}

fn create_animal(kind: &str) -> Box<dyn Animal> {
    match kind {
        "dog" => Box::new(Dog),
        "cat" => Box::new(Cat),
        _ => panic!("Unknown animal kind"),
    }
}

fn main() {
    let dog = create_animal("dog");
    dog.speak();
    
    let cat = create_animal("cat");
    cat.speak();
}

派生 Trait

Rust 提供了一些内置的 Trait,可以通过 #[derive] 属性自动实现:

rust
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 3, y: 4 };
    
    println!("p1: {:?}", p1);
    println!("p1 == p2: {}", p1 == p2);
    println!("p1 < p2: {}", p1 < p2);
    
    let p3 = p1.clone();
    println!("p3: {:?}", p3);
}

总结

  • Trait:定义共享行为的机制
  • 实现 Trait:为类型实现 Trait 中定义的方法
  • Trait 作为参数:实现多态
  • Trait 约束:指定泛型类型必须实现某个 Trait
  • Trait 作为返回类型:返回实现了某个 Trait 的类型
  • 派生 Trait:通过 #[derive] 属性自动实现内置 Trait

Trait 是 Rust 中实现代码复用和多态的重要机制。通过本章节的学习,你应该已经掌握了 Rust 中的 Trait 系统的基本概念和使用方法。