提问人:Lomírus 提问时间:2/6/2023 更新时间:2/7/2023 访问量:117
我可以编写与下面打字稿代码等效的 rust 代码吗?[已结束]
Can I write rust code equivalent to the typescript code below? [closed]
问:
下面是打字稿代码:
function gen(msg: string): () => Promise<void> {
return async function() {
// await any async function here ...
await sleep(1000);
console.log(msg);
}
}
直译为锈:
fn gen(msg: String) -> async fn() -> () {
async || {
sleep(1000).await;
println!("{}", msg);
}
}
但是编译器不允许这样的句子。
答:
4赞
Chayim Friedman
2/6/2023
#1
一个可能的(和正确的)翻译是:
use std::future::Future;
use std::pin::Pin;
fn gen(msg: String) -> impl Fn() -> Pin<Box<dyn Future<Output = ()>>> {
move || {
let msg = msg.clone();
Box::pin(async move {
sleep(1000).await;
println!("{}", msg);
})
}
}
但它不一定是最好的。Rust 不是 TypeScript,从字面上翻译代码是行不通的。
评论
1赞
Sven Marnach
2/7/2023
@FZs 因为我们无法摆脱封闭。或者换个说法,因为返回的函数可以多次调用。msg
Fn
gen()
0赞
FZs
2/7/2023
@SvenMarnach 哦,我明白了!
0赞
Babur Makhmudov
2/7/2023
#2
在 Rust 中,每个闭包都有一个独特的不透明类型,即使是看起来相同的闭包。async 增加了更多的唯一性,因为异步块会生成实现 Future trait 的唯一匿名类型。
你不能表达函数的返回类型,因为你根本不知道它,编译器会为你生成类型。因此,正如 @ChayimFriedman 在他的回答中所展示的那样,解决方案是简单地声明返回类型实现了一些特征(在本例中为 Fn),或者在返回闭包的返回类型的情况下,通过使用 trait 对象擦除异步块的任何类型。在 Box 内部,因为它没有已知的大小,而外部 Pin 是必需的,因为返回的 Future 类型需要在内存中有一个稳定的位置,以便在异步运行时执行(例如 或 )。gen
dyn impl Future
tokio
async-std
Rust 的类型系统与打字稿的类型系统完全不同,异步性也不是内置在语言中,而是作为各种库实现的,用户可以在必要时选择加入。这就是为什么语言之间的直接翻译并不总是可行的。
下一个:如何在闭包中访问孙子变量
评论