2013-07-08 6 views
4

я иногда ловлю себя писать абстрактные классы с частичной реализацией в 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; 
    } 
} 

Несмотря на мудрость такой структуры управления, как бы я выполнить это (частичную реализацию разделяемой) на функциональном языке, как ржавчина?

ответ

7

Использование стандартных методов по признакам является одним из способов (и, вероятно/многообещающе идиоматических путь в будущий, до недавнего времени метода struct -са-укупорочных @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), но они быстро улучшаются.

3

Я не в пределах досягаемости от компилятора ржавчины, так что простите сломанный код.

На функциональной стороне вещей, вы могли бы сделать структуру, которая содержит три функции и вызывать их

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

fn execute (e: Execution) -> bool { 
    ... 
} 

, но как только у вас есть функция в качестве первого значения класса, вы могли бы пройти, скажем, список boolean функции для проверки вместо фиксированных трех или что-то еще в зависимости от того, чего вы пытаетесь достичь.

На ржавчиной стороне вещей, вы можете сделать его более «объектно-ориентированный», используя черты

trait Executable { 
    fn execute(&self); 
} 

impl Execution { 
    fn execute(&self) { 
     ... 
    } 
}