Enn*_*ael 6 future rust async-await
tokio教程的select!状态:
需要注意的是,要等待引用,被引用的值必须被固定或实现 Unpin。
事实上,以下代码无法编译:
let fut = example(); // example is an async fn
(&mut fut).await;
Run Code Online (Sandbox Code Playgroud)
并出现以下错误消息:
error[E0277]: `from_generator::GenFuture<[static generator@src/main.rs:15:27: 17:2]>` cannot be unpinned
... snip ...
within `impl futures::Future<Output = i32>`, the trait `Unpin` is not implemented for `from_generator::GenFuture<[static generator@src/main.rs:15:27: 17:2]>
... snip ...
note: consider using `Box::pin`
Run Code Online (Sandbox Code Playgroud)
固定未来可以解决这个问题:
error[E0277]: `from_generator::GenFuture<[static generator@src/main.rs:15:27: 17:2]>` cannot be unpinned
... snip ...
within `impl futures::Future<Output = i32>`, the trait `Unpin` is not implemented for `from_generator::GenFuture<[static generator@src/main.rs:15:27: 17:2]>
... snip ...
note: consider using `Box::pin`
Run Code Online (Sandbox Code Playgroud)
为什么需要固定未来以等待对它的引用?
.await生成调用Future::poll. 第一个参数的类型为Pin<&mut Self>。的主要特征Pin<P>是它代表一个指向值的指针,该值在Pin<P>创建后保证永远不会移动,除非被指向者实现Unpin(这意味着它不关心它是否被移动)。
让我们首先回答:为什么没有必要固定一个 future 来按值等待它?也就是说,为什么这会起作用:
pub async fn foo() {
let fut = async {};
fut.await;
}
Run Code Online (Sandbox Code Playgroud)
很简单:fut.await消耗fut。
pub async fn foo() {
let fut = async {};
fut.await;
drop(fut); // error[E0382]: use of moved value: `fut`
}
Run Code Online (Sandbox Code Playgroud)
我们没有机会继续前进fut,fut.await所以我们不可能违反Pin上面的规则fut。
但是,如果我们可以引用.await,那么我们就可以将原始值移到 后面,如果是自引用,.await那将是灾难性的。fut
Future该错误来自编译器未能找到for the expression的实现&mut fut。impl<'_, F> Future for &'_ mut F where F: Future + Unpin + ?Sized标准库中有;但是,fut没有实现Unpin,所以这就是编译器在错误消息中报告的内容。
tokio::pin!(fut)首先移动fut(这就是宏如何确保它拥有未来的所有权),然后声明一个新类型fut的变量Pin<&mut F>(其中F是原始fut类型)。
tokio::pin!(fut)因此, uses下面的代码fut操作对未来的固定引用,而不是直接操作未来值。如果我们尝试移动fut,那么我们只需移动固定的参考。如果我们采用对 的可变引用fut,那么我们最终会得到对固定引用 ( ) 的引用&mut Pin<&mut F>。这种类型确实实现了,Future因为:
&mut F Unpin即使F不实施也实施UnpinPin<&mut F> 实施 Unpin因为&mut F实施UnpinPin<&mut F> 实施 Future因为F实施Future&mut Pin<&mut F> 实现, Future因为Pin<&mut F>同时实现Future和Unpin| 归档时间: |
|
| 查看次数: |
1932 次 |
| 最近记录: |