代码之家  ›  专栏  ›  技术社区  ›  Kitson

解析为未来的元组

  •  1
  • Kitson  · 技术社区  · 7 年前

    在《铁锈》中,我试图通过从文件中提取两位数据来实现未来 .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 ...

    2 回复  |  直到 7 年前
        1
  •  1
  •   Sven Marnach    7 年前

    元组的第一个元素是future,但第二个元素是future Option . 而 IntoFuture

    response.into_body() 消耗 response ,因此您以后无法访问它来检索标头。因为我们只有一个未来需要解决,所以最简单的解决方案是首先从响应中提取内容类型,然后将其附加到 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))
        });
    

    Full example code in the playground

    如果你仍然有困难使代码工作,我建议张贴一个问题,包括一个最小的例子,实际代码你试图编译以及实际的错误消息你得到。使用未来组合器的代码的错误消息可能会变得冗长和混乱,但它们仍然是理解代码为什么不能编译的最重要的信息。

        2
  •  0
  •   attdona    7 年前

    你的问题归结为:

    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 以你的例子来说:它是有效的,但要得到结果却相当复杂。另见下面的评论。

    推荐文章