决心为未来生成元组



在 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的错误...

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

元组的第一个元素是未来,但第二个元素是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))
});

操场上的完整示例代码

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

您的问题归结为:

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

用你的例子来玩:它有效,但获得结果非常复杂。另请参阅下面的评论。

最新更新