Rust 中的接口 Trait

在 Rust 中Trait 是类似其他语言中的接口,可以定义公用的接口方法,并且 Trait 可以定义默认的实现。

定义 Trait

pub trait Summary {
    fn summarize(&self) -> String;
    fn line(&self) {
        println!("----------------------------------------");
    }
}

定义一个结构体并实现 Summary Trait

这里我们只实现了 Summarysummarize 方法,line 已有默认实现,所以可以使用默认实现,也可以覆盖默认实现来用自己的实现方法。

主要调用 Trait 方法的语法,是以对象成员方法的方式,用对象.方法名的语法来调用。

struct Point {
    x: f64,
    y: f64,
}

impl Summary for Point {
    fn summarize(&self) -> String {
        format!(
            "Point Object Summary: x: {0}, y: {1}",
            self.x, self.y
        )
    }
}

fn main() {
    let p1 = Point { x: 12.21, y: 23.34};
    Point::info(&p1);
    println!("{}", p1.summarize());
    p1.line();
}

Trait 作为参数

Trait 作为参数,可以让一个函数接受任意一个实现了该 Trait 的类型作为参数。

在定义一个 Size 结构体,并且也实现 Summary Trait,然后定义一个 notify 方法,该方法的参数为 &impl Summary

struct Size {
    width: f64,
    height: f64,
}

impl Size {
    fn new(w: f64, h: f64) -> Self {
        Self {width: w, height: h}
    }
}

impl Summary for Size {
    fn summarize(&self) -> String {
        format!("Size Object Summary: width: {}, height: {}", self.width, self.height)
    }
}

fn notify(item: &impl Summary) {
    println!("Notify: {}", item.summarize());
}

fn main() {
    let p1 = Point { x: 12.21, y: 23.34};

    let s1 = Size {width: 23.2, height: 53.32};
    let s2 = Size::new(123.2, 32.32);

    notify(&p1);
    notify(&s1);
}

输出:

Notify: Point Object Summary: x: 12.21, y: 23.34
Notify: Size Object Summary: width: 23.2, height: 53.32

语法简化 Trait Bound 语法

简化前后的对比

fn notify(item: &impl Summary) {
    println!("Notify: {}", item.summarize());
}

fn notify<T: Summary>(item: &T) {
    println!("Notify: {}", item.summarize());
}

对于多个参数则会省去很多麻烦

fn notify<T: Summary>(item1: &T, item2: &T, item3: &T, item4: &T) {
    println!("Notify: {}", item.summarize());
	...
}

给参数指定多个 Trait

如果一个参数要使用多个 Trait 则可以通过 + 号来指定多个,语法如下

// 形式1
pub fn notify(item: &(impl Summary + Display))

// 形式2 基于泛型的语法
fn notify<T: Summary + Display>(item: &T) {
    println!("Notify: {}", item);
}

使用 Where 语法简化 Trait Bound 语法

where 语法就是把泛型中的参数进行简化,转移到 where 语法块里。

fn notify<T>(item: &T)
where
    T: Summary + Display
{
    println!("Notify: {}", item);
    println!("Notify: {}", item.summarize());
}
posted @ 2023-07-16 13:56  小土坡  阅读(68)  评论(0)    收藏  举报