是否可以注册发生 before/after 创建结构的事件?

Is it possible to register events that happen before/after creation of a struct?

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

struct Connection;

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

我希望能够注册发生的事件 before/after 创建任何 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 class,但在安全的 Rust 中这甚至可能吗?

据我所知,如果不改变用户与 Library 类型的交互方式,不可能

首先:没有 "real" 像在 OOP 意义上的构造函数,就像在 C++ 中一样。在这段代码中:

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

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

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

newwith_capacitydefault 等函数只是简单的关联(或 "static")函数,也没有什么特别之处。

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

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。那个工厂就是你需要的闭包。当然,您可以更改闭包签名来做更多有用的事情,例如返回布尔值以中止创建。

如果能够抓住所有可能的结构对您很重要,那么您必须 make a global mutable singleton