编辑:
我试图在函数中创建一个闭包向量,向该向量添加一个标准闭包,然后从该函数返回该向量。我搞错了人生冲突的问题。
代码可以执行这里。
fn vec_with_closure<'a, T>(f: Box<FnMut(T) + 'a>) -> Vec<Box<FnMut(T) + 'a>>
{
let mut v = Vec::<Box<FnMut(T)>>::new();
v.push(Box::new(|&mut: t: T| {
f(t);
}));
v
}
fn main() {
let v = vec_with_closure(Box::new(|t: usize| {
println!("{}", t);
}));
for c in v.iter_mut() {
c(10);
}
}
编辑2:
使用Rc<RefCell<...>>
和move ||
以及与Shepmaster建议的FnMut()
m相反的Fn()
特性,帮助我生成了上述代码的工作版本。生锈游戏笔版本这里。
发布于 2015-01-29 20:56:29
以下是我对这个问题的理解,稍微缩小了一些:
fn filter<F>(&mut self, f: F) -> Keeper
where F: Fn() -> bool + 'static //'
{
let mut k = Keeper::new();
self.subscribe(|| {
if f() { k.publish() }
});
k
}
在此方法中,f
是按值传入的值,这意味着filter
拥有它。然后,我们创建另一个通过引用捕获f
的闭包.然后我们试图在某个地方保存这个闭包,所以闭包中的所有引用都需要比我们的结构的生命周期长(我选择'static
是为了方便)。
然而,f
只存在于方法的末尾,所以它绝对不会活到足够长。我们需要使关闭拥有自己的f
。如果我们可以使用move
关键字是非常理想的,但是这会导致闭包也在k
中移动,因此我们无法从函数中返回它。
试图解决这个问题导致了这个版本:
fn filter<F>(&mut self, f: F) -> Keeper
where F: Fn() -> bool + 'static //'
{
let mut k = Keeper::new();
let k2 = &mut k;
self.subscribe(move || {
if f() { k2.publish() }
});
k
}
它有一个有用的错误消息:
error: `k` does not live long enough
let k2 = &mut k;
^
note: reference must be valid for the static lifetime...
...but borrowed value is only valid for the block
这导致了另一个问题:您试图在闭包中保留对k
的引用,但是一旦函数返回k
,该引用就会变得无效。当项按值移动时,它们的地址会改变,因此引用不再有效.
一个潜在的解决方案是使用Rc
和RefCell
fn filter<F>(&mut self, f: F) -> Rc<RefCell<Keeper>>
where F: Fn() -> bool + 'static //'
{
let mut k = Rc::new(RefCell::new(Keeper::new()));
let k2 = k.clone();
self.subscribe(move || {
if f() { k2.borrow_mut().publish() }
});
k
}
https://stackoverflow.com/questions/28223830
复制相似问题