特质
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(); }