Rust期货中的`then`,`and_then`和`or_else`有什么区别? [英] What is the difference between `then`, `and_then` and `or_else` in Rust futures?

查看:542
本文介绍了Rust期货中的`then`,`and_then`和`or_else`有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习使用Rust期货,并且感到非常困惑.我觉得自己很蠢,但是什么时候使用thenand_thenor_else?期望什么返回类型?

I am learning to use Rust futures and I am finding it extremely confusing. I feel like I am being stupid but when would then, and_then and or_else be used? What return types are expected?

请提供一些您希望看到的不同情况的示例.

Please provide some examples of the different situations you would expect to see them.

推荐答案

TL; DR:无论将来是否成功,都要使用then时,and_then仅在以下情况下运行闭包未来成功,并且or_else仅在未来失败时运行闭包.

TL;DR: then is used when you want to do something regardless of if the future was successful or not, and_then runs the closure only when the future succeeded, and or_else runs the closure only when the future failed.

and_thenor_elseResult上同名方法的直接类似物.

and_then and or_else are direct analogs to the methods of the same name on Result .

您的第一步应该是阅读文档.该文档包含准确的方法签名(解释了期望的类型和返回类型),描述每个方法的散文以及示例用法.

Your first step should be to read the docs. The documentation contains the exact method signatures (which explain what types it expects and what the return types are), prose describing each method, and example usage as well.

我提取了文档的小片段,并强调了相关部分.

I've extracted small snippets of the docs and emphasized the relevant parts.

Future::then :

此功能可用于确保不管是否运行计算 未来的结论.提供的关闭将产生 Result未来完成后.

This function can be used to ensure a computation runs regardless of the conclusion of the future. The closure provided will be yielded a Result once the future is complete.

闭包的返回值必须实现IntoFuture特征 并可以代表未来的更多工作 完成.

The returned value of the closure must implement the IntoFuture trait and can represent some more work to be done before the composed future is finished.

Future::and_then :

此功能可用于将两个期货链接在一起并确保 最终的未来直到双方都完成后才能解决.这 提供的关闭操作产生了这个未来的成功结果,并且 返回另一个可以转换为未来的值.

This function can be used to chain two futures together and ensure that the final future isn't resolved until both have finished. The closure provided is yielded the successful result of this future and returns another value which can be converted into a future.

Future::or_else

返回一个成功的期货,如果成功则返回该期货的价值,否则将错误传递给闭包f ,并等待其返回的未来.

Return a future that passes along this future's value if it succeeds, and otherwise passes the error to the closure f and waits for the future it returns.

这三种方法的返回类型都是可以转换为另一个未来的任何类型.

The return type for all three methods is any type that can be converted into another future.

  • then:对返回类型没有其他限制.
  • and_then要求返回的将来的错误类型与开始的将来的错误类型相匹配.
  • or_else要求返回的未来的成功类型与开始的未来的成功类型相匹配.
  • then: no additional restrictions on the return type.
  • and_then requires that the error type of the returned future match the starting future's error type.
  • or_else requires that the success type of the returned future match the starting future's success type.
use futures::{future, Future}; // 0.1.25

struct Error;

fn download_from_server(server: u8) -> impl Future<Item = Vec<u8>, Error = Error> {
    /* ... */
}

fn upload_to_server(data: Vec<u8>) -> impl Future<Item = usize, Error = Error> {
    /* ... */
}

// Uses `or_else` to do work on failure
fn download() -> impl Future<Item = Vec<u8>, Error = Error> {
    download_from_server(0)
        .or_else(|_| download_from_server(1))
        .or_else(|_| download_from_server(2))
}

// Uses `and_then` to do work on success
fn reupload() -> impl Future<Item = usize, Error = Error> {
    download().and_then(|data| upload_to_server(data))
}

// Uses `then` to always do work
fn do_things() -> impl Future<Item = (), Error = ()> {
    reupload().then(|r| {
        match r {
            Ok(size) => println!("Uploaded {} bytes", size),
            Err(_) => println!("Got an error"),
        };
        Ok(())
    })
}

在Rust 1.39中稳定化的async/await语法简化了某些情况:

Some cases are simplified by the async / await syntax stabilized in Rust 1.39:

// Equivalent to `or_else`
async fn download() -> Result<Vec<u8>, Error> {
    match download_from_server(0).await {
        Ok(v) => Ok(v),
        Err(_) => match download_from_server(1).await {
            Ok(v) => Ok(v),
            Err(_) => download_from_server(2).await,
        },
    }
}

// Equivalent to `and_then`
async fn reupload() -> Result<usize, Error> {
    let data = download().await?;
    upload_to_server(data).await
}

// Equivalent to `then`
async fn do_things() -> Result<(), ()> {
    match reupload().await {
        Ok(size) => println!("Uploaded {} bytes", size),
        Err(_) => println!("Got an error"),
    }
    Ok(())
}

这篇关于Rust期货中的`then`,`and_then`和`or_else`有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆