我正在尝试创建一个将函数指针作为参数的异步函数。它会做一些事情,调用函数,等待结果,然后再做一些事情:
use std::future::Future;
async fn run_another_async_fn<F, Fut>(f: F)
where
Fut: Future<Output = ()>,
F: FnOnce(&mut i32) -> Fut,
{
let mut i = 42;
println!("running function");
f(&mut i).await;
println!("ran function");
}
async fn foo(i: &mut i32) {}
async fn bar() {
run_another_async_fn(foo);
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这无法编译:
error[E0308]: mismatched types
--> src/lib.rs:17:5
|
17 | run_another_async_fn(foo);
| ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected associated type `<for<'_> fn(&mut i32) -> impl Future {foo} as FnOnce<(&mut i32,)>>::Output`
found associated type `<for<'_> fn(&mut i32) -> impl Future {foo} as FnOnce<(&mut i32,)>>::Output`
= note: the required lifetime does not necessarily outlive the empty lifetime
note: the lifetime requirement is introduced here
--> src/lib.rs:6:28
|
6 | F: FnOnce(&mut i32) -> Fut,
| ^^^
Run Code Online (Sandbox Code Playgroud)
首先,编译器似乎完全找到了它的预期,但它仍然在抱怨?
其次,什么是“空人生”?我想它一定意味着'_,这有什么特殊意义吗?
最后,有什么方法可以编译它?
问题是无法在子句中为F和指定相同的生命周期。Futwhere
幸运的是(如果您不介意分配未来的堆)有一个简单的解决方法。您可以使用现有的,futures::future::BoxFuture;如下所示:
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
Run Code Online (Sandbox Code Playgroud)
借助它的帮助,您可以为借用指定相同的生命周期参数并作为未来的特征绑定:
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
Run Code Online (Sandbox Code Playgroud)
您还必须添加一个适配器函数,它将具有正确的返回类型 - 即而BoxFuture<'_, T>不是impl Future:
where for<'a> F: FnOnce(&'a mut i32) -> BoxFuture<'a, ()>,
Run Code Online (Sandbox Code Playgroud)
或使用闭包:
fn asd(i: &mut i32) -> BoxFuture<'_, ()> {
foo(i).boxed()
}
Run Code Online (Sandbox Code Playgroud)
结果你的代码将如下所示:
run_another_async_fn(|i| foo(i).boxed());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
156 次 |
| 最近记录: |