我正在学习使用Rust期货,并且发现它非常令人困惑。我觉得自己很蠢,但是什么时候使用then
,and_then
和or_else
?期望什么返回类型?
请提供一些您希望看到的不同情况的示例。
答案 0 :(得分:4)
TL; DR:then
用于无论将来是否成功都想做某事,and_then
仅在将来成功时才运行闭包,而or_else
仅在将来失败时才运行关闭。
and_then
和or_else
是Result
上同名方法的直接类似物。
您的第一步应该是阅读文档。该文档包含确切的方法签名(说明了期望的类型和返回的类型),描述每种方法的散文以及示例用法。
我提取了文档的小片段并强调了相关部分。
此功能可用于确保不管 未来的结论。提供的关闭将产生
Result
一旦未来完成。闭包的返回值必须实现
IntoFuture
特征 并可以代表未来的更多工作 完成。
此功能可用于将两个期货链接在一起并确保 最终的未来直到双方都完成后才能解决。的 所提供的关闭是这个未来的成功结果,并且 返回另一个可以转换为未来的值。
返回一个成功的期货,如果成功,则该期货的价值将通过,否则将错误传递给闭包
f
,并等待其返回。
这三种方法的返回类型都是可以转换为另一个未来的任何类型。
then
:对返回类型没有其他限制。and_then
要求返回的期货的错误类型与起始期货的错误类型相匹配。or_else
要求返回的未来的成功类型与开始的未来的成功类型匹配。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(())
})
}