什么是特征?
本课属于 Coddy Rust 学习旅程的“面向对象编程”单元。第 29 课,共 61 课。
泛型让你可以编写适用于任意类型的代码,但有时你需要确保某个类型能够完成特定操作。这时就需要用到特征。
trait 定义了一组类型必须实现的方法。你可以把它看作一份契约:任何“签署”这份契约的类型,都承诺提供指定的行为。如果你在其他语言中用过接口,trait 的作用与接口类似。
下面介绍如何定义一个特征:
trait Describable {
fn describe(&self) -> String;
}
trait 关键字用于引入 trait,后面跟着它的名称。在花括号内,你要声明方法签名,也就是方法名称、参数和返回类型,不包含方法体。签名后的分号表示这是一个要求,而不是具体实现。
这个 Describable 特征表示:“任何实现了它的类型都必须提供一个 describe 方法,该方法接收自身的引用并返回一个 String。”这个特征不关心该方法如何工作:这由实现它的每种类型自行决定。
当多个不同类型都实现同一个特征时,特征就会变得更强大。Book、Car 和 Person 都可以实现 Describable,并各自提供独特的描述。这个特征保证它们都具有这一共同能力。
挑战
简单来定义你的第一个 trait!trait 会确立一份契约:任何实现它的类型都承诺提供特定行为。你将创建一个 Summarizable trait,不同类型都可以实现它,以提供自身的摘要。
你将把代码分成两个文件:
summary.rs:定义一个名为Summarizable的公共 trait,其中只有一个方法签名:summarize(&self) -> String。请记住,在 trait 定义中,你只需要用分号声明方法签名,不需要方法体。这会告诉 Rust:“任何实现此 trait 的类型都必须提供一个summarize方法,并返回一个String。”main.rs:引入 summary 模块,并打印一条消息,确认你的 trait 已定义。我们还没有学过如何实现 trait(这是下一课的内容!),所以你只需验证 trait 能正确编译。
在主文件中,打印以下消息,以确认你的 trait 定义有效:
Summarizable trait defined successfully!这个挑战只关注 trait 定义语法:trait 关键字、trait 名称,以及如何声明尚未实现的方法签名。下一课中,你将学习如何让结构体实现这个 trait!
亲手试试
mod summary;
fn main() {
// TODO: 输出确认 trait 已定义的消息
// 预期输出:"Summarizable trait defined successfully!"
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Rust 在线编译器