可以使用以下代码片段就地修改函数参数:
let mut foo = 1;
let mut fun: Box<dyn FnMut(&mut i32) -> _> = Box::new(|f| {
*f += 1;
});
fun(&mut foo);
assert_eq!(foo, 2);
然而,我有这样一个例子,函数fun
需要返回一个future,一旦future被等待,它就修改参数。基本上我有下面的场景:
let mut foo = 1;
assert_eq!(foo, 1);
let mut fun: Box<dyn FnMut(&mut i32) -> _> = Box::new(|f| {
async move {
*f += 1;
}
});
fun(&mut foo).await;
assert_eq!(foo, 2);
rust playground
但这会产生编译错误:
error: lifetime may not live long enough
--> src/main.rs:7:9
|
6 | let mut fun: Box<dyn FnMut(&mut i32) -> _> = Box::new(|f| {
| -- return type of closure `impl Future<Output = ()>` contains a lifetime `'2`
| |
| has type `&'1 mut i32`
7 | / async move {
8 | | *f += 1;
9 | | }
| |_________^ returning this value requires that `'1` must outlive `'2`
error: could not compile `playground` due to previous error
我不知道如何在上面的代码片段中注解生存期。我已经尝试过Box<dyn FnMut(&'static mut i32) -> _>
,但这表明foo
的生存期不够长。
有没有办法让它工作?
2条答案
按热度按时间ezykj2lf1#
您不能简单地更改(可能)来自另一个线程的值,而不使用一些同步原语将其打包。
相反,您可以将它与
Arc
和Mutex
打包,并像处理多线程程序一样处理它:2izufjch2#
我尝试将函数
fun
移动到泛型函数定义中,而不是对其进行装箱,这似乎是可行的:这似乎是可行的,因为我可以在这个设置中注解生存期。这个解决方案要求我立即等待它,因为
&mut i32
一次只能存在于一个地方。也就是说,下面的方法行不通: