特质
trait 是为未知类型 Self 定义的一组方法集合。这些方法可以访问同一 trait 中声明的其他方法。
trait 可以为任何数据类型实现。在下面的例子中,我们定义了 Animal,一组方法的集合。然后为 Sheep 数据类型实现 Animal trait,这样就可以对 Sheep 使用 Animal 中的方法。
struct Sheep { naked: bool, name: &'static str }
trait Animal {
// 关联函数签名;`Self` 指代实现者类型。
fn new(name: &'static str) -> Self;
// 方法签名;这些方法将返回一个字符串。
fn name(&self) -> &'static str;
fn noise(&self) -> &'static str;
// trait 可以提供默认的方法实现。
fn talk(&self) {
println!("{} 说 {}", self.name(), self.noise());
}
}
impl Sheep {
fn is_naked(&self) -> bool {
self.naked
}
fn shear(&mut self) {
if self.is_naked() {
// 实现者的方法可以使用实现者的 trait 方法。
println!("{} 已经剃过毛了...", self.name());
} else {
println!("{} 剃了个毛!", self.name);
self.naked = true;
}
}
}
// 为 `Sheep` 实现 `Animal` trait
impl Animal for Sheep {
// `Self` 是实现者类型,即 `Sheep`
fn new(name: &'static str) -> Sheep {
Sheep { name: name, naked: false }
}
fn name(&self) -> &'static str {
self.name
}
fn noise(&self) -> &'static str {
if self.is_naked() {
"咩~?"
} else {
"咩~!"
}
}
// 可以重写默认的 trait 方法
fn talk(&self) {
// 例如,我们可以添加一些安静的思考
println!("{} 短暂停顿…… {}", self.name, self.noise());
}
}
fn main() {
// 在这种情况下需要类型标注
let mut dolly: Sheep = Animal::new("多莉");
// TODO ^ 尝试移除类型标注
dolly.talk();
dolly.shear();
dolly.talk();
}