我想在异步上下文中多次重复某个用户提供的函数。因此,我想到了一个非异步关闭,它产生了可以消费/等待的期货。
一个最低限度的可重现性例子如下:
let counter = Arc::new(AtomicU64::new(0));
let counter_closure = counter.clone();
let future_producer = move || async {
counter_closure.fetch_add(1, Ordering::SeqCst);
};但是这会导致这个错误。
562 | let future_producer = move || async {
| _______________________________-------_^
| | | |
| | | return type of closure `impl Future<Output = ()>` contains a lifetime `'2`
| | lifetime `'1` represents this closure's body
563 | | counter_closure.fetch_add(1, Ordering::SeqCst);
564 | | };
| |_________^ returning this value requires that `'1` must outlive `'2`我该如何解决这个问题?
发布于 2022-09-04 19:09:04
问题是,封市拥有counter_closure,但封市返回的期货仅指该关闭所拥有的价值。闭包的签名不能表达这一点。这类似于“拥有迭代器”问题--比如Iterator特性不允许表示迭代器分发与其自身生命周期相关的引用的情况,可以在引用闭包时调用的闭包特征系列(Fn和FnMut)无法表示从闭包返回的值借用闭包本身。
如果编译器允许这样编译,那么就有可能在以前返回的期货仍然存在的时候放弃关闭,从而创造一种免费使用的情况。这会在counter_closure还被借来的时候毁掉它。
您可以通过在每次调用闭包之前在counter_closure块上克隆闭包拥有的counter_closure来修复这个问题,并使用async move将这个克隆转移到将来。
let counter = Arc::new(AtomicU64::new(0));
let counter_closure = counter.clone();
let future_producer = move || {
let counter_inner = counter_closure.clone();
async move {
counter_inner.fetch_add(1, Ordering::SeqCst);
}
};这让未来拥有自己的Arc,从而使未来的生命从封闭中分离出来。
https://stackoverflow.com/questions/73602016
复制相似问题