Rust 中的特质 trait

55 阅读2分钟

定义特征

如果不同的类型具有相同的行为,那么我们就可以定义一个特征,然后为这些类型实现该特征。定义特征是把一些方法组合在一起,目的是定义一个实现某些目标所必需的行为的集合。

例如,我们现在有文章 Post 和微博 Weibo 两种内容载体,而我们想对相应的内容进行总结,也就是无论是文章内容,还是微博内容,都可以在某个时间点进行总结,那么总结这个行为就是共享的,因此可以用特征来定义:

pub trait Summary {
    fn summarize(&self) -> String;
}

这里使用 trait 关键字来声明一个特征,Summary 是特征名。在大括号中定义了该特征的所有方法,在这个例子中是: fn summarize(&self) -> String。

特征只定义行为看起来是什么样的,而不定义行为具体是怎么样的。因此,我们只定义特征方法的签名,而不进行实现,此时方法签名结尾是 ;,而不是一个 {}。

为类型实现特征

因为特征只定义行为看起来是什么样的,因此我们需要为类型实现具体的特征,定义行为具体是怎么样的。

首先来为 Post 和 Weibo 实现 Summary 特征:

use std::fmt::format;

trait Summary{
    fn summarize(&self) -> String;
}

struct Post{
    title: String,
    author: String,
    content: String,
}

impl Summary for Post{
    fn summarize(&self) -> String {
        format!("文章名称:{} 文章作者:{}", self.title, self.author)
    }
}

pub struct Weibo {
    pub username: String,
    pub content: String
}

impl Summary for Weibo {
    fn summarize(&self) -> String {
        format!("{}发表了微博{}", self.username, self.content)
    }
}

fn main() {
    let post = Post{
        title: "Rust语言简介".to_string(),
        author: "Sunface".to_string(),
        content: "Rust棒极了!".to_string()
    };
    let weibo = Weibo{
        username: "sunface".to_string(),
        content: "好像微博没Tweet好用".to_string()
    };

    println!("{}",post.summarize());
    println!("{}",weibo.summarize());
}

// 文章名称:Rust语言简介 文章作者:Sunface
// sunface发表了微博好像微博没Tweet好用