Rust 特征trait

trait类似于java中的接口

基本定义

trait Printable {
    fn format(&self) -> String;
}

为类型实现trait

struct Book {
    title: String,
    pages: u32,
}

impl Printable for Book {
    fn format(&self) -> String {
        format!("《{}》({})页", self.title, self.pages);
    }
}

泛型trait

trait Converter<T> {
    fn convert(&self) -> T;
}

impl Converter<f64> for Book {
    fn convert(&self) -> f64 {
        self.pages as f64
    }
}

泛型约束

fn print_info<T: Printable> (item: T) {
    println!("{}", item.format());
}
// 等价于
fn print_info(item: impl Printable) {
    println!("{}", item.format());
}

// 返回值实现trait
fn create_printable() -> impl Printable { }

条件实现

// 根据类型特征选择性实现
impl<T: Display> Printable for T {

}

trait继承

trait Animal: Printable + Clone {
    fn speak(&self);
}

动态分发

多态, 用&dyn Trait表示一个trait对象的引用,可变引用&mut dyn Trait
由两个指针组成,一个指向实际类型,一个执行改类型实现trait方法的函数指针表

对象安全

只有满足以下条件的trait才能作为dyn Trait使用

  1. 方法不能返回Self
  2. 方法不能使用泛型参数
  3. 方法不能携带 Sized 约束(where Self: Sized)
trait Animal {
    fn speak(&self);
}

struct Cat;
struct Dog;

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

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

fn main() {
    let cat = Cat;
    let dog = Dog;
    let animals: Vec<&dyn Animal> = vec![&cat, &dog];
    for animal in animals {
        animal.speak();
    }
}
posted @ 2025-05-01 21:03  店里最会撒谎白玉汤  阅读(13)  评论(0)    收藏  举报