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

Events 是否可以注册在创建结构之前/之后发生的事件?,events,rust,observer-pattern,Events,Rust,Observer Pattern,我有以下连接结构和一个简单的构造函数: struct Connection; impl Connection { pub fn new() -> Connection { // before constructor let construct = Connection; // after constructor construct } } 我希望能够注册在创建任何连接之前/之后发生的事件。比如说 register!(Conn

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

struct Connection;

impl Connection {
   pub fn new() -> Connection {
      // before constructor
      let construct  = Connection;
      // after constructor
      construct
   }
}
我希望能够注册在创建任何
连接之前/之后发生的事件。比如说

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 

我认为这需要一个静态的
可观察的
类,但即使在安全的情况下也可能这样吗?

AFAIK如果不改变用户与
类型的交互方式,这是不可能的

首先,在OOP中没有像C++那样的“真实”构造函数。在此代码中:

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

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

让f=Foo{/AFAIK在不改变用户与
类型的交互方式的情况下,是不可能的

首先,没有像OC++一样的“真实”构造函数,就像C++一样。
struct Foo { 
    x: i32,
    y: bool,
}

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

让f=Foo{/这是可能的,但它不是内置于语言中的。您可以理解这种决策的每一个细微差别:

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
}
mod连接{
pub结构连接;
impl连接{
fn new()->连接{
联系
}
}
发布结构连接工厂{
之前:Vec,
之后:Vec,
}
impl连接工厂{
pub fn new()->ConnectionFactory{
连接工厂{
befores:Vec::new(),
after:Vec::new(),
}
}
发布fn寄存器在前(&mut self,f:f)
其中F:Fn()+'静态
{
self.befores.push(Box::new(f))
}
发布fn寄存器\u后(&mut self,f:f)
其中F:Fn()+'静态
{
自后推(框::新(f))
}
发布fn生成(和自)->连接{
对于f in&self.befores{f()}
设c=Connection::new();
对于f in&self.after{f()}
C
}
}
}
使用连接::*;
fn main(){
让mut f=ConnectionFactory::new();
f、 在之前注册(| | println!(“在1之前”);
f、 在之前注册(| | println!(“在2之前”);
f、 在之后注册(| | println!(“之后”);
f、 build();
//Connection::new();//错误:方法'new'是私有的
}
重要的是,
Connection::new
不再是公共的,构建一个连接的唯一方法是通过一个
ConnectionFactory
。这个工厂就是用来保存您需要的闭包的。当然,您可以更改闭包签名来做更多有用的事情,比如返回布尔值以中止创建


如果能够抓住每一个可能的结构对你来说都很重要,那么你必须这样做。

这是可能的,但它不是语言固有的。你可以理解这样一个决定的每一个细微差别:

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
}
mod连接{
pub结构连接;
impl连接{
fn new()->连接{
联系
}
}
发布结构连接工厂{
之前:Vec,
之后:Vec,
}
impl连接工厂{
pub fn new()->ConnectionFactory{
连接工厂{
befores:Vec::new(),
after:Vec::new(),
}
}
发布fn寄存器在前(&mut self,f:f)
其中F:Fn()+'静态
{
self.befores.push(Box::new(f))
}
发布fn寄存器\u后(&mut self,f:f)
其中F:Fn()+'静态
{
自后推(框::新(f))
}
发布fn生成(和自)->连接{
对于f in&self.befores{f()}
设c=Connection::new();
对于f in&self.after{f()}
C
}
}
}
使用连接::*;
fn main(){
让mut f=ConnectionFactory::new();
f、 在之前注册(| | println!(“在1之前”);
f、 在之前注册(| | println!(“在2之前”);
f、 在之后注册(| | println!(“之后”);
f、 build();
//Connection::new();//错误:方法'new'是私有的
}
重要的是,
Connection::new
不再是公共的,构建一个连接的唯一方法是通过一个
ConnectionFactory
。这个工厂就是用来保存您需要的闭包的。当然,您可以更改闭包签名来做更多有用的事情,比如返回布尔值以中止创建


如果能够捕获每一个可能的构造对您来说都很重要,那么您必须。

我的意思是,您可以确保除了
::new()之外,没有任何东西可以访问struct
类似构造函数。我选择的是最小示例,这意味着我不会编写完整的结构声明。我的意思是,除了
::new()
类似构造函数之外,我可以确保任何东西都无法访问结构。我选择的是最小示例,这意味着我不会编写完整的结构声明。