解决未来的元组

Resolve to a tuple for a future

在 Rust 中,我试图通过使用超级客户端作为元组从 .get 请求中提取两位数据来实现未来。问题是结果类型不 work.

所以给出这样的代码:

let result = client
  .get(url)
  .map_err(|err| Error::from(err))
  .and_then(|response| {
    (response
      .into_body()
      .concat2()
      .map(|body| String::from_utf8(body.to_vec()).unwrap())
      .map_err(|err| Error::from(err)),
    response
      .headers()
      .get(CONTENT_TYPE)
      .map(|content_type| content_type.to_str()))
  });

我收到类似 the trait "futures::IntoFuture" is not implemented for...

的错误

我很确定这是因为元组的两个成员是期货,可以处理,但元组不是,但我不确定如何解析期货的值并将它们放置成一个元组。

元组的第一个元素是未来,但第二个元素是 Option。虽然 IntoFuture 是为元组实现的,但只要所有元素都实现它并且错误类型匹配,你只有一个未来要解决,所以有一个更简单的解决方案。

另一个问题是 response.into_body() 消耗了 response,因此您以后无法访问它来检索 headers。由于我们只有一个未来要解决,最简单的解决方案是先从响应中提取内容类型,然后将其附加到 map() 方法中的结果:

let result = client
    .get("https://www.whosebug.com/".parse().unwrap())
    .map_err(|err| Error::from(err))
    .and_then(|response| {
        let content_type = response
            .headers()
            .get(CONTENT_TYPE)
            .map(|content_type| content_type.to_str().unwrap().to_string());
        response
            .into_body()
            .concat2()
            .map(|body| (
                String::from_utf8(body.to_vec()).unwrap(),
                content_type,
            ))
            .map_err(|err| Error::from(err))
    });

Full example code in the playground

如果您仍然无法使代码正常工作,我建议您发布一个问题,其中包括您尝试编译的实际代码的最小示例以及您收到的实际错误消息。使用 future 组合器的代码的错误消息可能会变得冗长且令人困惑,但它们仍然是了解代码为何无法编译的最重要的信息。

您的问题归结为:

use futures::*;

struct Foo {}

impl Future for Foo {
    type Item = u32;
    type Error = u32;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        Ok(Async::Ready(100))
    }
}

fn main() {
    let f = Foo {};

    let _result = f
        .and_then(|val| {
            (val * 2, val * 4)
        });
}

这给出:

   |                                    
18 |  .and_then(|val| {
   |   ^^^^^^^^ the trait `futures::future::IntoFuture` is not implemented for `(u32, u32)`

顺便说一下 IntoFuture 是为 Result 实现的:

impl<T, E> IntoFuture for Result<T, E>

对于the tuple

impl<A, B> IntoFuture for (A, B) 
where
    A: IntoFuture,
    B: IntoFuture<Error = A::Error>,

返回结果元组有效:

use futures::*;

struct Foo {}

impl Future for Foo {
    type Item = u32;
    type Error = u32;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        Ok(Async::Ready(100))
    }
}

fn main() {
    let f = Foo {};

    let _result = f
        .and_then(|val| {
            (Ok(val * 2), Ok(val * 4))
        });
}

playground 以您的示例为例:它有效,但获得结果非常复杂。另请参阅下面的评论。