gpt4 book ai didi

closures - 存储捕获返回值的闭包时存在冲突的生命周期要求

转载 作者:行者123 更新时间:2023-11-29 08:19:23 25 4
gpt4 key购买 nike

编辑:

我正在尝试在一个函数内创建一个闭包向量,向该向量添加一个标准闭包,然后从该函数返回该向量。我收到有关生命周期冲突的错误。

代码可以执行here .

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 ||Fn()FnMut() 相对的特征我按照 Shepmaster 的建议帮助我生成了上述代码的工作版本。 Rust围栏版here .

最佳答案

这是我对这个问题的理解,稍微精简了:

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 by-reference 的闭包。然后我们试图将该闭包保存在某个地方,因此闭包中的所有引用都需要比我们的结构的生命周期更长(为了方便,我选择了 '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 从功能。当项目按值移动时,它们的地址将发生变化,因此引用不再有效。

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

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
}

关于closures - 存储捕获返回值的闭包时存在冲突的生命周期要求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28223830/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com