2016-01-22 94 views
0

我有以下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类,但是,甚至有可能在安全锈?

回答

4

这是可能的,但它不是内置于该语言。你得明白这样一个决定的每一个细微差别:

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不再公开,构建一个唯一的方法是通过ConnectionFactory。那个工厂就是你需要的封闭物。当然你可以改变闭包签名来做更多有用的事情,比如返回一个布尔值来中止创建。

如果你能抓住每一个可能的建筑物,那么你必须make a global mutable singleton

0

AFAIK它是而不是而不改变用户如何与Library类型进行交互。首先:没有像OOP意义上的“真实”构造函数,就像在C++中一样。在此代码中:

struct Foo { 
    x: i32, 
    y: bool, 
} 

let f = Foo { // <-- this 
    x: 0, 
    y: true, 
}; 

...标记的点只是一个结构初始值设定项。它只是分配值并且不执行任意代码。在你的代码中,... = Connection;部分就是这种简单的初始化程序。

new,with_capacitydefault这些函数只是简单的关联(或“静态”)函数,没有什么特别之处。

+0

我的意思是可以确保没有什么会像构造函数那样访问除':: new()之外的任何结构。我正在寻找**最小的**例子,这意味着我不会写完整的结构声明。 –

相关问题