1 个不稳定版本
0.1.0 | 2021 年 12 月 20 日 |
---|
#7 在 #挂起
8KB
67 行代码(不包括注释)
挂起函数
免责声明:这主要是为了证明以下提案的概念。我没有测试这个宏是否有性能成本。
此包提供了一个 proc-macro,它消除了使用 await
关键字的需要。例如
#[suspend_fn]
fn visit_rustlang() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://www.rust-lang.net.cn")?;
let text = response.text()?;
println!("{}", text);
text.len(); // sync functions work just fine!
Ok(())
}
上面的代码在功能上与以下代码等效
async fn visit_rustlang() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://www.rust-lang.net.cn").await?;
let text = response.text().await?;
println!("{}", text);
text.len();
Ok(())
}
挂起块
您还可以使用类似于 async
和 async move
块的 suspend!
和 suspend_move!
宏。请注意,这些可能会提示样式警告,因此我建议将 #![allow(unused_parens)]
放在 crate 根目录中。
#![allow(unused_parens)]
suspend! {
let response = reqwest::get("https://www.rust-lang.net.cn")?;
let text = response.text()?;
println!("{}", text);
text.len();
}
限制
目前,该宏在内部宏中不起作用。例如
println!("{}", async_fn());
上面的代码将引发以下错误消息
| println!("{}", async_fn());
| ^^^^^^^^^^ `impl Future` cannot be formatted with the default formatter
在这种情况下,您可以在宏中自己使用 .await
。
动机
在最近的一篇博客文章中讨论异步取消问题,有人认为异步析构函数会导致从语言设计角度不一致。这是因为编译器将为异步析构函数引入 .await
调用,使得一些 .await
调用是隐式的,而另一些是显式的。
作为解决这种冲突的一种方式,有人提出了完全删除 .await
语法。虽然我认为从人体工程学角度来看这将非常棒,但我不希望看到这样大的破坏性变化。作为替代方案,我建议添加一个新关键字,类似于 async
,暂时让我们使用 Kotlin 的 suspend
。
然后我们就可以有
suspend fn function() {
/*
implicit await with implicit calls to async destructors
*/
}
async fn function() {
/*
explicit await with explicit calls to async destructors
*/
}
async {
/*
explicit await with explicit calls to async destructors
*/
}
suspend {
/*
implicit await with implicit calls to async destructors
*/
}
相关主题
依赖项
~1.5MB
~35K SLoC