特徵的繼承
在 Rust 中,沒有繼承結構屬性的概念。相反,當你設計物件之間的關係時,請通過介面( Rust 中的特徵 ) 定義一個人的功能。這促進了組合而不是繼承 ,這被認為更有用,更容易擴充套件到更大的專案。
這是在 Python 中使用一些示例繼承的示例:
class Animal:
def speak(self):
print("The " + self.animal_type + " said " + self.noise)
class Dog(Animal):
def __init__(self):
self.animal_type = 'dog'
self.noise = 'woof'
為了將其轉化為 Rust,我們需要取出構成動物的內容並將該功能納入特徵。
trait Speaks {
fn speak(&self);
fn noise(&self) -> &str;
}
trait Animal {
fn animal_type(&self) -> &str;
}
struct Dog {}
impl Animal for Dog {
fn animal_type(&self) -> &str {
"dog"
}
}
impl Speaks for Dog {
fn speak(&self) {
println!("The dog said {}", self.noise());
}
fn noise(&self) -> &str {
"woof"
}
}
fn main() {
let dog = Dog {};
dog.speak();
}
請注意我們如何將該抽象父類拆分為兩個獨立的元件:將結構定義為動物的部分以及允許它發聲的部分。
精明的讀者會注意到這並不是一對一的,因為每個實施者都必須重新實現邏輯,以“The {animal} say {noise}”的形式列印出一個字串。你可以通過稍微重新設計我們為 Animal
實現 Speak
的介面來做到這一點:
trait Speaks {
fn speak(&self);
}
trait Animal {
fn animal_type(&self) -> &str;
fn noise(&self) -> &str;
}
impl<T> Speaks for T where T: Animal {
fn speak(&self) {
println!("The {} said {}", self.animal_type(), self.noise());
}
}
struct Dog {}
struct Cat {}
impl Animal for Dog {
fn animal_type(&self) -> &str {
"dog"
}
fn noise(&self) -> &str {
"woof"
}
}
impl Animal for Cat {
fn animal_type(&self) -> &str {
"cat"
}
fn noise(&self) -> &str {
"meow"
}
}
fn main() {
let dog = Dog {};
let cat = Cat {};
dog.speak();
cat.speak();
}
現在請注意,動物會產生噪音並簡單地說現在已經實現了任何動物。這比以前的方式和 Python 繼承更靈活。例如,如果你想新增一個具有不同聲音的 Human
,我們可以改為使用 speak
的另一個實現 Human
:
trait Human {
fn name(&self) -> &str;
fn sentence(&self) -> &str;
}
struct Person {}
impl<T> Speaks for T where T: Human {
fn speak(&self) {
println!("{} said {}", self.name(), self.sentence());
}
}