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()
类似构造函数之外,我可以确保任何东西都无法访问结构。我选择的是最小示例,这意味着我不会编写完整的结构声明。