Methods 构建器是否可以使用所创建对象的方法注册回调?
给定:对象Methods 构建器是否可以使用所创建对象的方法注册回调?,methods,callback,closures,rust,builder,Methods,Callback,Closures,Rust,Builder,给定:对象Foo和FooBuilder。FooBuilder必须创建对象,并使用所创建对象的方法注册回调。在这种情况下,生成器充当对象Foo的高级自定义,该对象需要根据收到的事件进行更改。静态方法不是强制性的,但仍然是可取的。main()的末尾是事件循环 #[macro_use] extern crate lazy_static; use std::sync::Mutex; struct Global { callbacks: Vec<Box<Fn(i32) + 'st
Foo
和FooBuilder
。FooBuilder
必须创建对象,并使用所创建对象的方法注册回调。在这种情况下,生成器充当对象Foo
的高级自定义,该对象需要根据收到的事件进行更改。静态方法不是强制性的,但仍然是可取的。main()的末尾是事件循环
#[macro_use]
extern crate lazy_static;
use std::sync::Mutex;
struct Global {
callbacks: Vec<Box<Fn(i32) + 'static + Send + Sync>>
}
lazy_static! {
static ref GLOBAL: Mutex<Global> = {
Mutex::new(Global {
callbacks: Vec::new()
})
};
}
struct FooBuilder {
c: i32
}
impl FooBuilder {
fn new() -> FooBuilder {
FooBuilder {
c: 0
}
}
fn build(&self) -> Foo {
let foo = Foo {
f: self.c
};
// foo.set_callback(|x| foo.edit());
// ^ ERROR
foo
}
}
struct Foo {
f: i32
}
impl Foo {
fn edit(&mut self) {
self.f += 1;
println!("{:?}", self.f);
}
fn set_callback<F>(&self, f: F)
where F: Fn(i32) + 'static + Send + Sync {
GLOBAL.lock().unwrap().callbacks.push(Box::new(f));
}
}
fn main() {
let foo = FooBuilder::new().build();
/* event loop */
}
#[宏使用]
外部板条箱(静态);
使用std::sync::Mutex;
结构全局{
回调:Vec不适用于您的情况
考虑代码的这一部分:
fn set_callback<F>(&self, f: F)
where F: Fn(i32) + 'static + Send + Sync
从您编辑的评论中:
那么这种方法就不太合适了
问题在于,您对问题建模的方式充满了危险,铁锈正在阻止您自食其果。您只能拥有一个对项的可变引用。除此之外,您还试图在函数调用之间共享对堆栈分配项的引用
也许您会更乐意使用一种更接近垃圾收集语言可能创建的解决方案
在这里,我们使用允许多个线程共享单个可变项。我们使用,以便多个线程可以共享该项的所有权
我还将set\u callback
移动到了一个自由函数,因为它与您之前启用的结构没有关系
调用set\u callback
时,我们克隆了增加引用计数的Arc
,并将该克隆提供给全局队列。由于Mutex
具有内部可变性,因此函数可以保持Fn
#[macro_use]
extern crate lazy_static;
use std::sync::{Mutex,Arc};
struct Global {
callbacks: Vec<Box<Fn(i32) + 'static + Send + Sync>>
}
fn set_callback<F>(f: F)
where F: Fn(i32) + 'static + Send + Sync
{
GLOBAL.lock().unwrap().callbacks.push(Box::new(f));
}
lazy_static! {
static ref GLOBAL: Mutex<Global> = {
Mutex::new(Global {
callbacks: Vec::new()
})
};
}
struct FooBuilder;
impl FooBuilder {
fn build(&self) -> Arc<Mutex<Foo>> {
let foo = Arc::new(Mutex::new(Foo));
let inner_foo = foo.clone();
set_callback(move |_| inner_foo.lock().unwrap().edit());
foo
}
}
struct Foo;
impl Foo {
fn edit(&mut self) {}
}
fn main() {
let _foo = FooBuilder.build();
}
#[宏使用]
外部板条箱(静态);
使用std::sync::{Mutex,Arc};
结构全局{
回调:Vec Arc{
设foo=Arc::new(Mutex::new(foo));
让internal_foo=foo.clone();
设置回调(移动| |内部| foo.lock().unwrap().edit());
福
}
}
结构Foo;
impl-Foo{
fn编辑(&mut self){}
}
fn main(){
让_foo=FooBuilder.build();
}
不适用于您的情况
考虑代码的这一部分:
fn set_callback<F>(&self, f: F)
where F: Fn(i32) + 'static + Send + Sync
从您编辑的评论中:
那么这种方法就不太合适了
问题在于,您对问题建模的方式充满了危险,铁锈正在阻止您自食其果。您只能拥有一个对项的可变引用。除此之外,您还试图在函数调用之间共享对堆栈分配项的引用
也许您会更乐意使用一种更接近垃圾收集语言可能创建的解决方案
在这里,我们使用允许多个线程共享单个可变项。我们使用,以便多个线程可以共享该项的所有权
我还将set\u callback
移动到了一个自由函数,因为它与您之前启用的结构没有关系
调用set\u callback
时,我们克隆了增加引用计数的Arc
,并将该克隆提供给全局队列。由于Mutex
具有内部可变性,因此函数可以保持Fn
#[macro_use]
extern crate lazy_static;
use std::sync::{Mutex,Arc};
struct Global {
callbacks: Vec<Box<Fn(i32) + 'static + Send + Sync>>
}
fn set_callback<F>(f: F)
where F: Fn(i32) + 'static + Send + Sync
{
GLOBAL.lock().unwrap().callbacks.push(Box::new(f));
}
lazy_static! {
static ref GLOBAL: Mutex<Global> = {
Mutex::new(Global {
callbacks: Vec::new()
})
};
}
struct FooBuilder;
impl FooBuilder {
fn build(&self) -> Arc<Mutex<Foo>> {
let foo = Arc::new(Mutex::new(Foo));
let inner_foo = foo.clone();
set_callback(move |_| inner_foo.lock().unwrap().edit());
foo
}
}
struct Foo;
impl Foo {
fn edit(&mut self) {}
}
fn main() {
let _foo = FooBuilder.build();
}
#[宏使用]
外部板条箱(静态);
使用std::sync::{Mutex,Arc};
结构全局{
回调:Vec Arc{
设foo=Arc::new(Mutex::new(foo));
让internal_foo=foo.clone();
设置回调(移动| |内部| foo.lock().unwrap().edit());
福
}
}
结构Foo;
impl-Foo{
fn编辑(&mut self){}
}
fn main(){
让_foo=FooBuilder.build();
}
请在你的问题中添加准确的错误信息。你应该进一步最小化你的示例,只要它不改变错误信息(例如用{a,b}
删除)。请在你的问题中添加准确的错误信息。你应该进一步最小化你的示例,只要它不改变错误信息(例如,{ A,B } /代码>),如果我们考虑回调作为外部API的注册,有可能使它更漂亮吗?如果我们考虑回调作为外部API的注册,有可能使它更漂亮吗?