How do you share implementation details in a functional language such as rust?

Sometimes I have to write abstract classes with partial implementation in 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; } } 

Regardless of the wisdom of such a management structure, how could I accomplish this (partial joint implementation) in a functional language such as rust?

+4
source share
2 answers

Using the default methods for tags is one way (and probably will be an idiomatic way in the future, until recently, the struct -with-closures @Slartibartfast method showed the only thing that really worked):

 #[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 } 

Please note: it is possible that the Executable implementation may override execute at the moment (I opened a question about a #[no_override] that would disable this).

In addition, the default methods are experimental and prone to failing the compiler (yes, moreover than the rest of Rust), but they are rapidly improving.

+7
source

I'm not within reach of the rust compiler, so forgive the broken code.

On the functional side of things, you can create a structure that contains three functions and call them

 struct Execution { before: @fn() -> bool, during: @fn() -> bool, after: @fn() -> bool } fn execute (e: Execution) -> bool { ... } 

but as soon as you have a function as the value of the first class, you can pass say, a list of logical functions that need to be checked instead of fixed three, or something else depending on what you are trying to achieve.

On the rust side of things, you can make it more “object oriented” using traits

 trait Executable { fn execute(&self); } impl Execution { fn execute(&self) { ... } } 
+3
source

Source: https://habr.com/ru/post/1490214/


All Articles