等待结果映射未来

问题描述:

我正在使用future库,我有一个未来实现Future<T, E>。我想用一个函数FnOnce(T) -> D来映射这个未来,其中D: From<E>。现在,当我希望wait()为finsih这个未来,我会得到一个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荷兰国际集团)?

+0

这可能是比较容易回答,如果你提供一个完整的代码示例,以及您想避免'match'ing。 –

+0

@PeterHall好的,我编辑了我的问题。 – torkleyy

我发现了一个问题的答案:

您只需先wait未来去完成,使用?返回一个潜在的错误,然后将其应用于parse

parse(f.wait()?) 

这应该具有相同的语义,因为在轮询时,由map返回的Future执行其关闭。另一种解决方案是映射一个可能的错误,并使用and_then

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

很高兴你知道了。 '''真的收拾东西! –

+0

请注意,出于“期货”的目的,组合通常应该优先于等待的明确调用,它可以扩展并保持异步性。 无论如何,后一行代码可以更简洁地写为'f.from_err()。and_then(parse).wait()'。 – dippi