对于编写一个非常大的程序,我认为没有办法减轻必须为每个使用某种共享行为的结构编写相同的代码。
例如,Dog 可能会“吠叫”:
struct Dog {
is_barking: bool,
....
}
impl Dog {
pub fn bark(self) {
self.is_barking = true;
emit_sound("b");
emit_sound("a");
emit_sound("r");
emit_sound("k");
self.is_barking = false;
}
....
}
这种狗的许多品种可能存在:struct Poodle {
unique_poodle_val: &str
}
impl Poodle {
pub fn unique_behaviour(self) {
self.some_behaviour();
}
}
struct Rottweiler {
unique_rottweiler_val: u32
}
impl Rottweiler{
pub fn unique_behaviour(self) {
self.some_behaviour();
}
}
问题是,以我目前的知识,Rust 似乎无法做到这一点,但它需要完成,我需要一个解决方法:因此,我问:
既然 Poodle 和罗威纳犬的吠叫方式完全相同,那么如何在不重写每个模块中的 bark() 的情况下实现 bark() 呢?
请提供一个如何在 Rust 代码中解决这个问题的例子,欢迎使用惯用的和稍微有点 hacky 的解决方案,但请说明它们是什么,因为我仍在学习 Rust。
谢谢你。
编辑: bool 值不是线程的东西,而是在做某事之前设置一些状态的一个例子,即emit_sound 在这个状态内。我们放入 bark() 的任何代码都有同样的问题。对结构变量的访问是不可能的,比如特征。
最佳答案
你已经指出了 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 trait 是有意义的,它有一个通用的实现并声明一些处理状态的函数: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 语言中的继承)。
关于rust - 如何在 Rust 中编写共享行为而不在每个模块中重复相同的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68756315/