首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >存储闭包捕获返回值时的冲突生存期要求

存储闭包捕获返回值时的冲突生存期要求
EN

Stack Overflow用户
提问于 2015-01-29 20:18:39
回答 1查看 881关注 0票数 2

编辑:

我试图在函数中创建一个闭包向量,向该向量添加一个标准闭包,然后从该函数返回该向量。我搞错了人生冲突的问题。

代码可以执行这里

代码语言:javascript
运行
复制
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()特性,帮助我生成了上述代码的工作版本。生锈游戏笔版本这里

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-29 20:56:29

以下是我对这个问题的理解,稍微缩小了一些:

代码语言:javascript
运行
复制
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中移动,因此我们无法从函数中返回它。

试图解决这个问题导致了这个版本:

代码语言:javascript
运行
复制
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
}

它有一个有用的错误消息:

代码语言:javascript
运行
复制
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,该引用就会变得无效。当项按值移动时,它们的地址会改变,因此引用不再有效.

一个潜在的解决方案是使用RcRefCell

代码语言:javascript
运行
复制
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
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28223830

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档