我写了下面的代码,但我不能写生命时间约束来工作并得到一个错误:
use futures::Future;
async fn foo<'a>(a: &'a str) -> &'a str {
let task = get();
f(a, task).await
}
async fn f<T>(v: T, task: impl Future<Output = T>) -> T {
if true {
v
} else {
task.await
}
}
async fn get() -> &'static str {
"foo"
}
Run Code Online (Sandbox Code Playgroud)
错误:
error[E0759]: `a` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
--> src/lib.rs:3:18
|
3 | async fn foo<'a>(a: &'a str) -> &'a str {
| ^ ------- this data with lifetime `'a`...
| |
| ...is captured here...
4 | let task = get();
5 | f(a, task).await
| - ...and is required to live as long as `'static` here
Run Code Online (Sandbox Code Playgroud)
我认为如果函数中的两个参数f可以有自己的生命周期就可以解决。例如,
error[E0759]: `a` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
--> src/lib.rs:3:18
|
3 | async fn foo<'a>(a: &'a str) -> &'a str {
| ^ ------- this data with lifetime `'a`...
| |
| ...is captured here...
4 | let task = get();
5 | f(a, task).await
| - ...and is required to live as long as `'static` here
Run Code Online (Sandbox Code Playgroud)
如何解决这个问题?
可以使用另一个最小示例来重现相同的问题,使用函数接口而不是异步函数。
fn get() -> impl FnOnce() -> &'static str {
|| "foo"
}
fn foo<'a, T: 'a, F>(_: &'a str, _: F)
where
F: Fn() -> T,
T: FnOnce() -> &'a str,
{
}
let x = "".to_string();
foo(&*x, &get);
Run Code Online (Sandbox Code Playgroud)
fn get() -> impl FnOnce() -> &'static str {
|| "foo"
}
fn foo<'a, T: 'a, F>(_: &'a str, _: F)
where
F: Fn() -> T,
T: FnOnce() -> &'a str,
{
}
let x = "".to_string();
foo(&*x, &get);
Run Code Online (Sandbox Code Playgroud)
这个例子允许我们变成get一个函数参数,并观察到传递这个函数对生命周期施加了严格的约束。尽管程序有最好的意图,但返回供应商函数(或承诺)的函数并不提供关于输出生命周期的协方差。也就是说,不满足。有时,编译器会建议您坚持最薄弱的环节,即生命周期,即使这可能并不理想。'a'static() -> &'static strfor<'a> () -> &'a str'static
请注意,表示在其生命周期内通用的类型的方法目前非常有限。这些是较高种类类型的一种形式,只能通过较高等级的特征边界指定某种程度的表达能力(一旦完全实现并稳定,最终将成为通用关联类型)。在这种情况下,与其尝试f为某种类型(伪代码)工作,不如在整个生命周期T<'a>中使我们的泛型更好。然后可以在实现时进行子类型化,因为我们知道字符串文字可以满足任何生命周期。get'a
fn get<'a>() -> impl FnOnce() -> &'a str {
|| "foo"
}
Run Code Online (Sandbox Code Playgroud)
在这种async情况下(游乐场):
async fn get<'a>() -> &'a str {
"foo"
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
| 归档时间: |
|
| 查看次数: |
186 次 |
| 最近记录: |