作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
看下面的代码:
#![feature(async_closure)]
use std::future::Future;
use std::pin::Pin;
trait A<'a> {
fn call(&'a self, data: &'a i32) -> Pin<Box<dyn 'a + Future<Output=()>>>;
}
impl <'a, F, Fut> A<'a> for F
where Fut: 'a + Future<Output=()>,
F: Fn(&'a i32) -> Fut
{
fn call(&'a self, data: &'a i32) -> Pin<Box<dyn 'a + Future<Output=()>>> {
Box::pin(self(data))
}
}
async fn sample(_data: &i32) {
}
fn is_a(_: impl for<'a> A<'a>) {
}
fn main() {
is_a(sample);
is_a(async move |data: &i32| {
println!("data: {}", data);
});
}
is_a(sample)
可以工作,但是下一行无法编译?异步fn和异步闭包之间的生存期推断有什么区别?
error: implementation of `A` is not general enough
--> src/main.rs:29:5
|
6 | / trait A<'a> {
7 | | fn call(&'a self, data: &'a i32) -> Pin<Box<dyn 'a + Future<Output=()>>>;
8 | | }
| |_- trait `A` defined here
...
29 | is_a(async move |data: &i32| {
| ^^^^ implementation of `A` is not general enough
|
= note: `A<'1>` would have to be implemented for the type `[closure@src/main.rs:29:10: 31:6]`, for any lifetime `'1`...
= note: ...but `A<'_>` is actually implemented for the type `[closure@src/main.rs:29:10: 31:6]`, for some specific lifetime `'2`
最佳答案
async ||
闭包的返回类型是由编译器生成的匿名类型。
这种类型实现了Future
并捕获了一个额外的
生存期与async ||
闭包的范围有关。
fn main() {
let closure = async move |data: &i32| { --+ '2 start
println!("data: {}", data); |
}; |
|
is_a(closure); |
v
}
impl Future<Output = SomeType> + '2 + '...
'2
是闭包的生存期。
is_a
时:
let closure = async move |data: &i32| {
println!("data: {}", data);
};
is_a(closure);
error: implementation of `A` is not general enough
...
= note: `A<'1>` would have to be implemented for the type `[closure@src/main.rs:43:19: 45:6]`, for any lifetime `'1`...
= note: ...but `A<'_>` is actually implemented for the type `[closure@src/main.rs:43:19: 45:6]`, for some specific lifetime `'2`
closure
参数是为特定生存期
'2
实现的类型,但是任何生存期都是必需的:
fn is_a(_: impl for<'a> A<'a>) {}
'2
生命周期的生命周期违规。
let closure = async move |data: &i32| {
println!("data: {}", data);
};
error: lifetime may not live long enough
--> src/main.rs:43:19
|
43 | let closure = async move |data: &i32| {
| ^^^^^^^^^^^^^^^^^^-^^^-
| | | |
| | | return type of closure is impl std::future::Future
| | let's call the lifetime of this reference `'1`
| returning this value requires that `'1` must outlive `'2`
async ||
闭包内使用参数引用。
fn my_function() {
let value = 1 --+ '1 start
|
let closure = async move |data: &i32| { | --+ '2 start
println!("data: {}", data); | |
}; | |
| |
tokio::spawn(closure(&value)) | |
-+ '1 end |
} v continue until
the future complete
my_function
返回,堆栈展开。
'1
返回时,生存期
value
考虑了
my_function
的有效范围
&value
无效。
'2
从何而来?
closure(&value)
返回一个实现
Future
的实体,该实体将存在于运行时执行程序中,
'2
生存期将考虑
Future
的有效性范围。
'2
生存期成为必要,请考虑以下情形:
fn run_asyn_closure() {
let data: i32 = 1;
let closure = async move |data: &i32| {
println!("starting task with data {}", data);
// yield the computation for 3 seconds, awaiting for completion of long_running_task
long_running_task().await;
// data points to a memory slot on the stack that meantime is rewritten
// because run_asyn_closure returned 3 seconds ago
println!("using again data: {}", data); // BANG!! data is not more valid
};
tokio::spawn(closure(&data));
}
tokio::spawn
需要
&data
引用具有
'static
生存期,
关于rust - 异步fn和异步闭包之间的生存期推断有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60751127/
我正在使用身份服务器 3 保护 Web 应用程序。我的应用程序分为 2 个 oidc 客户端,一个 ASP.Net MVC 客户端和一个使用 oidc-client javascript 库的 jav
我正在使用 Silex 构建一个小型后台项目,我正在使用 PdoSessionHandler 将 session 存储在数据库中。我已经成功地将 session 存储在数据库中,但似乎将 cookie
我是一名优秀的程序员,十分优秀!