1个不稳定版本
0.1.0 | 2021年12月20日 |
---|
#7 in #suspend
每月51次下载
在suspend_fn中使用
16KB
456 行
suspend fn
免责声明:这个项目主要是作为下面提议的实验概念。我没有测试这个宏是否有性能成本。
这个crate提供了一个过程宏,用于移除对await
关键字的需求。例如
#[suspend_fn]
fn visit_rustlang() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://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://rust-lang.net.cn").await?;
let text = response.text().await?;
println!("{}", text);
text.len();
Ok(())
}
suspend块
您还可以像对async
和async move
块一样使用suspend!
和suspend_move!
宏。注意,这可能会触发样式警告,因此我建议在crate根目录中放置#![allow(unused_parens)]
。
#![allow(unused_parens)]
suspend! {
let response = reqwest::get("https://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