您已经指出了 Rust 今天做得不好的事情:简洁地向结构添加基于内部数据和函数的行为。
解决这个问题的最典型的方法可能是将 Barking 隔离在所有狗拥有的结构中(当有疑问时,更喜欢组合而不是继承):
pub struct Barking {
is_barking: bool,
}
impl Barking {
pub fn do_it(&mut self) {
self.is_barking = true; // <- this makes no sense in rust, due to the ownership model
println!("bark");
println!("a");
println!("r");
println!("k");
self.is_barking = false;
}
}
struct Poodle {
unique_poodle_val: String,
barking: Barking,
}
impl Poodle {
pub fn unique_behaviour(self) {
println!("some_behaviour");
}
pub fn bark(&mut self) {
self.barking.do_it();
}
}
struct Rottweiler {
unique_rottweiler_val: u32,
barking: Barking,
}
impl Rottweiler{
pub fn unique_behaviour(self) {
println!("unique behavior");
}
pub fn bark(&mut self) {
// maybe decide to bite instead
self.barking.do_it();
}
}
在某些情况下,定义 Barking 特征是有意义的,具有通用的实现并声明一些函数来处理状态:
pub trait Barking {
fn bark(&mut self) {
self.set_barking(true);
println!("bark");
println!("a");
println!("r");
println!("k");
self.set_barking(false);
}
fn set_barking(&mut self, b: bool);
}
struct Poodle {
unique_poodle_val: String,
is_barking: bool,
}
impl Poodle {
pub fn unique_behaviour(self) {
println!("some_behaviour");
}
}
impl Barking for Poodle {
fn set_barking(&mut self, b: bool) {
self.is_barking = b;
}
}
请注意,这种半 OOP 方法通常会变得过于复杂且难以维护(如 OOP 语言中的继承)。