Rust 中的Trait 定义了特定类型所具有的功能,并且可以与其他类型共享。它指定了可以在类型上调用的方法。
例如,假设我们有不同类型的文本数据:
- 一个NewsArticle用于新闻报道的结构
- 和一个Tweet用于推文的结构。
两者都可以共享一个典型行为:总结内容。
我们使用Trait 来定义这种共享行为。
pub trait Summary { fn summarize(&self) -> String; }
|
Summary 特征Trait有一个summarize方法。任何实现此特征的类型都必须提供此方法的自身版本。
实现Trait
要实现Trait 特征,您需要为您的类型定义特征指定的方法。以下是我们对 NewsArticle 和 Tweet 的操作方法。
pub struct NewsArticle { pub headline: String, pub location: String, pub author: String, pub content: String, }
impl Summary for NewsArticle { fn summarize(&self) -> String { format!("{}, by {} ({})", self.headline, self.author, self.location) } }
pub struct Tweet { pub username: String, pub content: String, pub reply: bool, pub retweet: bool, }
impl Summary for Tweet { fn summarize(&self) -> String { format!("{}: {}", self.username, self.content) } }
|
现在,NewsArticle 和 Tweet 都可以使用 summary 方法。这允许我们在这些类型的实例上调用 summary。
默认实现
Trait 特征也可以有默认方法实现。如果我们不想为每种类型编写相同的方法,我们可以提供一个默认值:
pub trait Summary { fn summarize(&self) -> String { String::from("(Read more...)") } }
|
如果类型需要特定的行为,仍然可以覆盖此默认值。
使用Trait 作为参数
Trait 特征可用于定义函数参数。如果我们希望函数接受任何实现 Summary 的类型,我们可以这样写:
pub fn notify(item: &impl Summary) { println!("Breaking news! {}", item.summarize()); }
|
返回实现Trait 的类型
我们还可以指定一个函数返回一个实现Trait 特征的类型:
fn returns_summarizable() -> impl Summary { Tweet { username: String::from("horse_ebooks"), content: String::from("of course, as you probably already know, people"), reply: false, retweet: false, } }
|
这使我们能够返回符合 Summary 特征的不同类型,而无需暴露具体类型。
条件实现
有时,您希望仅当满足某些条件时方法才可用。Rust 允许条件实现:
impl<T: Display + PartialOrd> Pair<T> { fn cmp_display(&self) { if self.x >= self.y { println!("The largest member is x = {}", self.x); } else { println!("The largest member is y = {}", self.y); } } }
|
这里,仅当 T 同时实现了 Display 和 PartialOrd 时,cmp_display 才可用。
结论
Trait 特征是 Rust 中的一项强大功能,可帮助定义和共享跨类型行为。它们使您的代码更加模块化、可重用且更易于理解。通过将错误移至编译时,它们可确保您的代码稳健且高效。祝您编码愉快!