gpt4 book ai didi

rust - Rust future 中的 `then` 、 `and_then` 和 `or_else` 有什么区别?

转载 作者:行者123 更新时间:2023-11-29 08:02:02 25 4
gpt4 key购买 nike

我正在学习使用 Rust futures,但我发现它非常令人困惑。我觉得我很愚蠢但是什么时候使用thenand_thenor_else?预期返回类型是什么?

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

最佳答案

TL;DR:then 用于无论 future 是否成功都想做某事,and_then 仅在未来成功时运行闭包,并且 or_else 仅在 future 失败时运行闭包。

and_thenor_elseResult 上同名方法的直接类比。


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

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

Future::then :

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

The returned value of the closure must implement the IntoFuture traitand can represent some more work to be done before the composed futureis finished.

Future::and_then :

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

Future::or_else

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.

所有三个方法的返回类型都是可以转换为另一个 future 的任何类型。

  • then:对返回类型没有额外的限制。
  • and_then 要求返回的 future 的错误类型与起始 future 的错误类型匹配。
  • or_else 要求返回的 future 的成功类型与起始 future 的成功类型相匹配。

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 语法简化了一些情况:

// 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 - Rust future 中的 `then` 、 `and_then` 和 `or_else` 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55552413/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com