表达式 x.await 的语义是什么?

MrM*_*ter 3 rust async-await

我很好奇.awaitRust 的实际工作原理。它似乎不是FutureAPI 的一部分,所以我认为它一定是某种编译器魔法。它是如何.await工作的以及它可以应用于什么?

我了解异步构造的工作原理以及如何使用不稳定的生成器编译异步函数;这不是我的问题。我具体询问的是.await魔法会员运营商。也就是说,如果我们有这样的表达式

fut.await
Run Code Online (Sandbox Code Playgroud)

此时会发生什么以及fut该表达式应满足哪些约束才能有效?

She*_*ter 5

.await一个关键字,因此询问它是如何定义的就相当于询问如何定义ifor 。match真正的答案并不令人满意:看看Rust 编译器的代码

async /await RFC将其描述为:

编译器await!内置

await!编译器中添加了一个名为的内置函数。await!可用于“暂停”未来的计算,将控制权交还给调用者。 await!接受任何实现 的表达式IntoFuture,并计算出该 future 具有的项目类型的值。

// future: impl Future<Output = usize>
let n = await!(future);
Run Code Online (Sandbox Code Playgroud)

await 的扩展重复调用poll它接收到的 future,在它返回时产生对函数的控制Poll::Pending,并最终在它返回时计算出 item 值Poll::Ready

await!只能在异步函数、闭包或块内部使用。在该上下文之外使用它是一个错误。

await!是一个内置编译器,为稍后决定其确切语法留出空间。请参阅未解决的问题部分中的更多信息。)

等待的扩展

内置函数await!大致扩展为:

let mut future = IntoFuture::into_future($expression);
let mut pin = unsafe { Pin::new_unchecked(&mut future) };
loop {
    match Future::poll(Pin::borrow(&mut pin), &mut ctx) {
          Poll::Ready(item) => break item,
          Poll::Pending     => yield,
    }
}
Run Code Online (Sandbox Code Playgroud)

这不是字面扩展,因为这个yield概念不能用函数内的表面语法来表达async。这就是为什么await! 是内置编译器而不是实际宏的原因。

请注意,语法await!(expression)更改expression.await稳定之前的语法。

编译器是否具有该Future特征的神奇知识

是的。Future是一个语言项目

可以x是任何实现的东西IntoFuture还是更复杂?

IntoFuture标准库中实际上没有 an ;我认为在实现过程中不需要间接级别。.await仅适用于实现Future.

也可以看看: