我可以编写与下面打字稿代码等效的 rust 代码吗?[已结束]

Can I write rust code equivalent to the typescript code below? [closed]

提问人:Lomírus 提问时间:2/6/2023 更新时间:2/7/2023 访问量:117

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

10个月前关闭。

下面是打字稿代码:

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);
    }
}

但是编译器不允许这样的句子。

函数 rust async-await 闭包 函数指针

评论


答:

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 因为我们无法摆脱封闭。或者换个说法,因为返回的函数可以多次调用。msgFngen()
0赞 FZs 2/7/2023
@SvenMarnach 哦,我明白了!
0赞 Babur Makhmudov 2/7/2023 #2

在 Rust 中,每个闭包都有一个独特的不透明类型,即使是看起来相同的闭包。async 增加了更多的唯一性,因为异步块会生成实现 Future trait 的唯一匿名类型。

你不能表达函数的返回类型,因为你根本不知道它,编译器会为你生成类型。因此,正如 @ChayimFriedman 在他的回答中所展示的那样,解决方案是简单地声明返回类型实现了一些特征(在本例中为 Fn),或者在返回闭包的返回类型的情况下,通过使用 trait 对象擦除异步块的任何类型。在 Box 内部,因为它没有已知的大小,而外部 Pin 是必需的,因为返回的 Future 类型需要在内存中有一个稳定的位置,以便在异步运行时执行(例如 或 )。gendyn impl Futuretokioasync-std

Rust 的类型系统与打字稿的类型系统完全不同,异步性也不是内置在语言中,而是作为各种库实现的,用户可以在必要时选择加入。这就是为什么语言之间的直接翻译并不总是可行的。