- 此问题在此处已有答案**:
Calling a generic async function with a (mutably) borrowed argument(1个答案)
2天前关闭。
我试图将一个函数作为参数之一传递给另一个函数,但遇到了one type is more general than the other
错误。
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e4074efd53fdf9e43d8f209405745dc0
use std::future::Future;
async fn constraint<A, Fut, L>(args: A, lambda: L)
where
A: 'static + Send,
Fut: Future<Output = ()> + 'static,
L: Fn(&A) -> Fut + 'static,
{
lambda(&args).await;
}
fn main() {
constraint("hello".to_string(), lambda);
}
async fn lambda(_: &String) -> () {}
下面是错误消息:
error[E0308]: mismatched types
--> src/main.rs:13:5
|
13 | constraint("hello".to_string(), lambda);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected trait `for<'a> <for<'a> fn(&'a String) -> impl Future<Output = ()> {lambda} as FnOnce<(&'a String,)>>`
found trait `for<'a> <for<'a> fn(&'a String) -> impl Future<Output = ()> {lambda} as FnOnce<(&'a String,)>>`
note: the lifetime requirement is introduced here
--> src/main.rs:7:18
|
7 | L: Fn(&A) -> Fut + 'static,
| ^^^
For more information about this error, try `rustc --explain E0308`.
我不想改变lambda函数,因为我想在while循环中,用输入流中的第二个参数,多次调用它,但是我可以改变约束函数。
到目前为止,我试着给约束函数添加一个生存期,但我不确定这是否正确,因为A上应该已经有一个静态生存期:
async fn constraint<'a, A, Fut, L>(args: A, lambda: L)
where
A: 'static + Send,
Fut: Future<Output = ()> + 'static,
L: Fn(&'a A) -> Fut + 'static,
{
lambda(&args).await;
}
对应错误:
|
3 | async fn constraint<'a, A, Fut, L>(args: A, lambda: L)
| -- lifetime `'a` defined here
...
9 | lambda(&args).await;
| -------^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `args` is borrowed for `'a`
10 | }
| - `args` dropped here while still borrowed
还尝试移动参数,但得到相同的错误:
use std::future::Future;
async fn constraint<A, Fut, L>(args: A, lambda: L)
where
A: 'static + Send,
Fut: Future<Output = ()> + 'static,
L: Fn(&A) -> Fut + 'static,
{
async move {
lambda(&args).await;
};
}
fn main() {
constraint("hello".to_string(), lambda);
}
async fn lambda(_: &String) -> () {}
1条答案
按热度按时间mm5n2pyu1#
这是因为
lambda
的impl Future
返回类型隐式地捕获了它的参数的生存期,但是constraint
要求它是'static
(Fut: Future<Output = ()> + 'static
)你的
lambda
可以反糖为如下形式:它的输出有一个生存期绑定到它的输入参数。
虽然
constraint
期望签名看起来像这样:您可以只使用最后一个定义(不需要显式生存期
'a
)。我不确定是否以及如何使用
async
来表达这个意思