有时为 trait 中的某些或全部方法提供默认的行为,而不是在每个类型的每个实现中都定义自己的行为是很有用的。这样当为某个特定类型实现 trait 时,可以选择保留或重载每个方法的默认行为。
如何为 Summary trait 的 summarize 方法指定一个默认的字符串值。
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
#
# pub struct NewsArticle {
# pub headline: String,
# pub location: String,
# pub author: String,
# pub content: String,
# }
#
# impl Summary for NewsArticle {}
#
# 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 实例使用这个默认实现,而不是定义一个自己的实现,则可以通过 impl Summary for NewsArticle {}
指定一个空的 impl 块。
虽然我们不再直接为 NewsArticle 定义 summarize 方法了,但是我们提供了一个默认实现并且指定NewsArticle 实现 Summary trait。因此,我们仍然可以对 NewsArticle 实例调用 summarize 方法,如下所示:
#
# fn main() {
let article = NewsArticle {
headline: String::from("Penguins win the Stanley Cup Championship!"),
location: String::from("Pittsburgh, PA, USA"),
author: String::from("Iceburgh"),
content: String::from(
"The Pittsburgh Penguins once again are the best \
hockey team in the NHL.",
),
};
println!("New article available! {}", article.summarize());
# }
这段代码会打印 New article available! (Read more…)。
为 summarize 创建默认实现并不要求对 Tweet 上的 Summary 实现做任何改变。其原因是重载一个默认实现的语法与实现没有默认实现的 trait 方法的语法一样。
默认实现允许调用相同 trait 中的其他方法,哪怕这些方法没有默认实现。如此,trait 可以提供很多有用的功能而只需要实现指定一小部分内容。例如,我们可以定义 Summary trait,使其具有一个需要实现的summarize_author 方法,然后定义一个 summarize 方法,此方法的默认实现调用 summarize_author
方法:
fn summarize_author(&self) -> String;
fn summarize(&self) -> String {
format!("(Read more from {}...)", self.summarize_author())
}
}
#
# pub struct Tweet {
# pub username: String,
# pub content: String,
# pub reply: bool,
# pub retweet: bool,
# }
#
# impl Summary for Tweet {
# fn summarize_author(&self) -> String {
# format!("@{}", self.username)
# }
# }
为了使用这个版本的 Summary,只需在实现 trait 时定义 summarize_author 即可:
# pub trait Summary {
# fn summarize_author(&self) -> String;
#
# fn summarize(&self) -> String {
# format!("(Read more from {}...)", self.summarize_author())
# }
# }
#
# pub struct Tweet {
# pub username: String,
# pub content: String,
# pub reply: bool,
# pub retweet: bool,
# }
#
impl Summary for Tweet {
fn summarize_author(&self) -> String {
format!("@{}", self.username)
}
}
一旦定义了 summarize_author,我们就可以对 Tweet 结构体的实例调用 summarize 了,而 summarize的默认实现会调用我们提供的 summarize_author 定义。因为实现了 summarize_author,Summarytrait 就提供了 summarize 方法的功能,且无需编写更多的代码。
#
# fn main() {
let tweet = Tweet {
username: String::from("horse_ebooks"),
content: String::from(
"of course, as you probably already know, people",
),
reply: false,
retweet: false,
};
println!("1 new tweet: {}", tweet.summarize());
# }
这会打印出 1 new tweet: (Read more from @horse_ebooks…)。
注意无法从相同方法的重载实现中调用默认方法。