events - 是否可以注册在创建结构之前/之后发生的事件?

标签 events rust observer-pattern

我有以下 Connection 结构和一个简单的构造函数:

struct Connection;

impl Connection {
   pub fn new() -> Connection {
      // before constructor
      let construct  = Connection;
      // after constructor
      construct
   }
}

我希望能够注册在创建任何 Connection 之前/之后发生的事件。例如。

register!(Connection, before, println!("Before 1"));
register!(Connection, before, println!("Before 2"));
register!(Connection, after, println!("After"));

所以一旦我调用 Connection::new() 它至少应该尝试写:

//out: Before 1
//out: Before 2 
returns value
//out: After 

我认为这需要一个静态的 Observable 类,但是在安全的 Rust 中这甚至可能吗?

最佳答案

这是可能的,但它不是语言内置的。您将了解此类决定的每一个细微差别:

mod connection {
    pub struct Connection;

    impl Connection {
        fn new() -> Connection {
            Connection
        }
    }

    pub struct ConnectionFactory {
        befores: Vec<Box<Fn()>>,
        afters: Vec<Box<Fn()>>,
    }

    impl ConnectionFactory {
        pub fn new() -> ConnectionFactory {
            ConnectionFactory {
                befores: Vec::new(),
                afters: Vec::new(),
            }
        }

        pub fn register_before<F>(&mut self, f: F)
            where F: Fn() + 'static
        {
            self.befores.push(Box::new(f))
        }

        pub fn register_after<F>(&mut self, f: F)
            where F: Fn() + 'static
        {
            self.afters.push(Box::new(f))
        }

        pub fn build(&self) -> Connection {
            for f in &self.befores { f() }
            let c = Connection::new();
            for f in &self.afters { f() }
            c
        }
    }
}

use connection::*;

fn main() {
    let mut f = ConnectionFactory::new();
    f.register_before(|| println!("Before 1"));
    f.register_before(|| println!("Before 2"));
    f.register_after(|| println!("After"));

    f.build();

    // Connection::new(); // error: method `new` is private
}

重要的是 Connection::new 不再是公共(public)的,构建它的唯一方法是通过 ConnectionFactory。那个工厂就是你需要的闭包。当然,您可以更改闭包签名以执行更多有用的操作,例如返回 bool 值以中止创建。

如果能够捕捉到所有可能的结构对您来说很重要,那么您必须 make a global mutable singleton .

关于events - 是否可以注册在创建结构之前/之后发生的事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34949121/

相关文章:

java - getItem()、getSelectableItem() 和 getSource() 之间有什么区别?

c# - 如何使用控件(例如按钮)从表单调用事件?

ios - 手机间隙 : Calling an action when an app is opened after clicking the home button (iOS)

rust - Rust 中的局部函数

rust - 我如何在结构结束后留出空间以允许将来的 ABI 更改?

javascript - 主干模型更改事件仅触发一次

rust - std::process,带有来自缓冲区的 stdin 和 stdout

magento - 如何在 Magento 的观察者中获取付款方式?

java - 尝试插入扩展实体时出错: invalid column index

c# - 这是观察者反模式吗? (有奖金状态机问题)