2

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

所以给出一些这样的代码:

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...

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

4

2 回答 2

1

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

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

let result = client
    .get("https://www.stackoverflow.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))
    });

操场上的完整示例代码

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

于 2018-10-18T09:13:37.660 回答
0

您的问题归结为:

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>

对于元组

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))
        });
}

您的示例为例:它可以工作,但是要获得结果非常复杂。另请参阅下面的评论。

于 2018-10-18T11:54:10.187 回答