我有时会发现自己在C#中编写部分实现的抽象类:
abstract public class Executor {
abstract protected bool Before();
abstract protected bool During();
abstract protected bool After();
protected bool Execute() {
var success = false;
if (Before()) {
if (During()) {
if (After()) {
success = true;
}
}
}
return success;
}
}
尽管有这样一种控制结构的智慧,我怎么能用像rust这样的函数式语言来实现这个(部分共享实现)呢?
答案 0 :(得分:7)
在traits上使用默认方法是一种方式(并且很可能/希望将来成为惯用方法;直到最近,struct
- with-closures方法@Slartibartfast演示才是实际工作的唯一方法) :
#[allow(default_methods)];
trait Executable {
fn before(&self) -> bool;
fn during(&self) -> bool;
fn after(&self) -> bool;
fn execute(&self) -> bool {
self.before() && self.during() && self.after()
}
}
impl Executable for int {
fn before(&self) -> bool { *self < 10 }
fn during(&self) -> bool { *self < 5 }
fn after(&self) -> bool { *self < 0 }
// execute is automatically supplied, if it is not implemented here
}
请注意,Executable
的实现此时可能会覆盖execute
(我已打开an issue关于将禁用此内容的#[no_override]
属性
此外,默认方法是实验性的,容易导致编译器崩溃(是的,比Rust的其余部分更多),但它们正在迅速改进。
答案 1 :(得分:3)
我无法使用生锈编译器,因此请原谅破解的代码。
在功能方面,您可以创建一个包含三个函数并调用它们的结构
struct Execution {
before: @fn() -> bool,
during: @fn() -> bool,
after: @fn() -> bool
}
fn execute (e: Execution) -> bool {
...
}
但是一旦你有一个函数作为第一个类值,你可以传递一个布尔函数列表来检查而不是固定的三个,或者别的东西,这取决于你想要实现的目标。
事实上,你可以通过使用特征
使其更加“面向对象”trait Executable {
fn execute(&self);
}
impl Execution {
fn execute(&self) {
...
}
}