为什么我会得到终身不匹配?
Why am I getting a lifetime mismatch?
以下函数编译没有问题:
async fn filter_con<T, O, F>(arr: Vec<T>, predicate: F) -> Vec<T>
where
O: Future<Output = bool>,
F: for Fn(&T) -> O,
{
join_all(arr.into_iter().map(|it| async {
if predicate(&it).await {
Some(it)
} else {
None
}
}))
.await
.into_iter()
.filter_map(|p| p)
.collect::<Vec<_>>()
}
但是我找不到正确调用它的方法:
let items_filtered = filter_con(items, filter).await;
错误:
error[E0308]: mismatched types
--> src/lifecycle/querier.rs:101:30
|
101 | let items_filtered = filter_con(items_response, filter).await;
| ^^^^^^^^^^ lifetime mismatch
|
= note: expected associated type `<for<'_> fn(&PairInfo) -> impl futures::Future<Output = bool> {lifecycle::querier::filter} as FnOnce<(&PairInfo,)>>::Output`
found associated type `<for<'_> fn(&PairInfo) -> impl futures::Future<Output = bool> {lifecycle::querier::filter} as FnOnce<(&PairInfo,)>>::Output`
= note: the required lifetime does not necessarily outlive the empty lifetime
note: the lifetime requirement is introduced here
--> src/lifecycle/querier.rs:246:26
|
246 | F: for<'a> Fn(&T) -> O,
| ^
为什么会这样?
您遇到的问题与 here
中的问题基本相同
为了更容易理解,我将 rewrite/desugar 您的一些代码。让我们从谓词开始:
async fn filter(x: &Test) -> bool{
x.0 >= 50
}
在功能上等同于:
fn filter(x: &Test) -> impl Future<Output=bool> + '_{
async {
x.0 >= 50
}
}
现在应该很明显,返回的Future
的生命周期不是'static
,但实际上它取决于参数的生命周期x: &Test
。
这应该使错误更容易理解 - 你的谓词正在返回某个生命周期的未来,这是 not 在通用类型定义中的任何地方提到的 - 你可以看到你没有当你既没有定义 O
,也没有定义 F
:
时,请提及它
where
O: Future<Output = bool>,
F: for Fn(&T) -> O,
问题是,目前该语言没有提供任何方式来说明 O
的生命周期取决于 F
的生命周期。我知道的唯一简单的解决方案是使用逃生舱口 - box
未来,这将允许您在 F
和 O
中使用相同的生命周期。缺点是,F
将被分配到堆中:
use futures::future::{join_all, Future};
use futures::future::BoxFuture;
use futures::FutureExt;
#[derive(Debug)]
struct Test(usize);
#[tokio::main]
async fn main() {
let items = vec![Test(10), Test(100), Test(1000)];
let items_filtered = filter_con(items, filter).await;
println!("{:?}", items_filtered); // should print [100, 1000]
}
fn filter(x: &Test) -> BoxFuture<'_, bool>{
async {
x.0 >= 50
}.boxed()
}
async fn filter_con<T, F>(arr: Vec<T>, predicate: F) -> Vec<T>
where
F: for<'a> Fn(&'a T) -> BoxFuture<'a, bool>,
{
join_all(arr.into_iter().map(|it| async{
if predicate(&it).await {
Some(it)
} else {
None
}
}))
.await
.into_iter()
.filter_map(|p| p)
.collect::<Vec<_>>()
}
这里是link到Rust Plauground
以下函数编译没有问题:
async fn filter_con<T, O, F>(arr: Vec<T>, predicate: F) -> Vec<T>
where
O: Future<Output = bool>,
F: for Fn(&T) -> O,
{
join_all(arr.into_iter().map(|it| async {
if predicate(&it).await {
Some(it)
} else {
None
}
}))
.await
.into_iter()
.filter_map(|p| p)
.collect::<Vec<_>>()
}
但是我找不到正确调用它的方法:
let items_filtered = filter_con(items, filter).await;
错误:
error[E0308]: mismatched types
--> src/lifecycle/querier.rs:101:30
|
101 | let items_filtered = filter_con(items_response, filter).await;
| ^^^^^^^^^^ lifetime mismatch
|
= note: expected associated type `<for<'_> fn(&PairInfo) -> impl futures::Future<Output = bool> {lifecycle::querier::filter} as FnOnce<(&PairInfo,)>>::Output`
found associated type `<for<'_> fn(&PairInfo) -> impl futures::Future<Output = bool> {lifecycle::querier::filter} as FnOnce<(&PairInfo,)>>::Output`
= note: the required lifetime does not necessarily outlive the empty lifetime
note: the lifetime requirement is introduced here
--> src/lifecycle/querier.rs:246:26
|
246 | F: for<'a> Fn(&T) -> O,
| ^
为什么会这样?
您遇到的问题与 here
中的问题基本相同为了更容易理解,我将 rewrite/desugar 您的一些代码。让我们从谓词开始:
async fn filter(x: &Test) -> bool{
x.0 >= 50
}
在功能上等同于:
fn filter(x: &Test) -> impl Future<Output=bool> + '_{
async {
x.0 >= 50
}
}
现在应该很明显,返回的Future
的生命周期不是'static
,但实际上它取决于参数的生命周期x: &Test
。
这应该使错误更容易理解 - 你的谓词正在返回某个生命周期的未来,这是 not 在通用类型定义中的任何地方提到的 - 你可以看到你没有当你既没有定义 O
,也没有定义 F
:
where
O: Future<Output = bool>,
F: for Fn(&T) -> O,
问题是,目前该语言没有提供任何方式来说明 O
的生命周期取决于 F
的生命周期。我知道的唯一简单的解决方案是使用逃生舱口 - box
未来,这将允许您在 F
和 O
中使用相同的生命周期。缺点是,F
将被分配到堆中:
use futures::future::{join_all, Future};
use futures::future::BoxFuture;
use futures::FutureExt;
#[derive(Debug)]
struct Test(usize);
#[tokio::main]
async fn main() {
let items = vec![Test(10), Test(100), Test(1000)];
let items_filtered = filter_con(items, filter).await;
println!("{:?}", items_filtered); // should print [100, 1000]
}
fn filter(x: &Test) -> BoxFuture<'_, bool>{
async {
x.0 >= 50
}.boxed()
}
async fn filter_con<T, F>(arr: Vec<T>, predicate: F) -> Vec<T>
where
F: for<'a> Fn(&'a T) -> BoxFuture<'a, bool>,
{
join_all(arr.into_iter().map(|it| async{
if predicate(&it).await {
Some(it)
} else {
None
}
}))
.await
.into_iter()
.filter_map(|p| p)
.collect::<Vec<_>>()
}
这里是link到Rust Plauground