等待映射结果的Future

6
我正在使用futures库,并且我有一个实现了Future<T, E>的future。我想使用函数FnOnce(T) -> D将这个future映射为另一个future,其中D: From<E>。当我想要wait()等待此future完成时,会返回Result<Result<T, E>, D>,但我希望得到一个Result<T, D>
以下是更好理解的示例代码:
struct ReadError;

enum DownloadError {
    Read(ReadError),
    Parse(ParseError),
}

impl From<ReadError> for DownloadError { ... }

fn parse(bytes: [u8; 4]) -> Result<i32, DownloadError> { ... }

fn map_and_wait<F: Future<Item = [u8; 4]; Error = ReadError>>(f: F) -> Result<i32, DownloadError> {
    match f.map(|x| parse(x)).wait() {
        Ok(Ok(x)) => Ok(x),
        Ok(Err(x)) => Err(x.into()),
        Err(x) => Err(x),
    }
}

如果不使用匹配(match)的方法,最简单、易于理解的方式是什么?


如果您提供一个完整的代码示例,并标明您想要避免匹配的match,那么回答可能会更容易。 - Peter Hall
@PeterHall 好的,我已经编辑了我的问题。 - torkleyy
1个回答

4

这是 futures v0.1 版本(旧版,实验性的)

我找到了一个答案:

你可以先等待 future 完成,使用 ? 返回可能的错误,然后再对其应用 parse

parse(f.wait()?)

这段代码应该具有相同的语义,因为通过调用map返回的Future会执行它的闭包。另一种解决方案是对可能出现的错误进行映射并使用and_then

f.map_error(|x| x.into()).and_then(|x| parse(x)).wait()

太好了,你找到解决办法了。真的让事情变得整洁! - Peter Hall
请注意,为了实现“futures”的目的,通常应该优先使用组合而不是显式调用等待,因为它是可扩展的并且保留异步性。无论如何,后一行代码可以更简洁地编写为f.from_err().and_then(parse).wait() - dippi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接