我想使用一个返回Vec<String>
的Future,在Future流中对其进行迭代,并将值赋予另一个Future,并应处理该Future的结果。完整的事情也应该是未来。
走什么路?我已经尝试了不同的方法,并且遇到了我不理解的类型问题。
为什么会有这些嵌套的将来结果类型签名?这不是最终结果吗?为什么编译器不知道类型?
error[E0631]: type mismatch in closure arguments
--> src/lib.rs:45:18
|
45 | .then(|x: Result<(), ()>| ok(()))
| ^^^^ -------------------------- found signature of `fn(std::result::Result<(), ()>) -> _`
| |
| expected signature of `fn(std::result::Result<std::vec::Vec<tokio::prelude::future::Then<tokio::prelude::future::Then<impl tokio::prelude::Future, tokio::prelude::future::FutureResult<(), ()>, [closure@src/lib.rs:35:31: 41:26]>, tokio::prelude::future::FutureResult<(), _>, [closure@src/lib.rs:42:31: 42:57]>>, _>) -> _`
我为此设置了一个Playground
extern crate tokio;
use tokio::prelude::future::ok;
use tokio::prelude::*;
#[allow(dead_code)]
pub fn test_future<F>(f: F) -> Result<F::Item, F::Error>
where
F: IntoFuture,
F::Future: Send + 'static,
F::Item: Send + 'static,
F::Error: Send + 'static,
{
let mut runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime");
runtime.block_on(f.into_future())
}
#[allow(dead_code)]
fn fut(el: &String) -> impl Future<Item = String, Error = std::io::Error> {
ok((el.to_string() + "-ok").to_string())
}
#[test]
fn reporting_future_result_test() {
let v = vec![
vec!["a".to_string(), "b".to_string()],
vec!["a".to_string(), "b".to_string()],
];
let f = stream::iter_ok(v.iter().cloned())
.map(|el: Vec<String>| {
stream::iter_ok(el.iter().cloned())
.map(|ell: String| {
fut(&ell)
.then(|x: Result<String, std::io::Error>| {
match x {
Ok(s) => println!("{}", s),
Err(e) => println!("{:?}", e),
};
ok(())
})
.then(|x: Result<(), ()>| ok(()))
})
.collect()
.then(|x: Result<(), ()>| ok(()))
})
.collect()
.then(|x: Result<Vec<_>, std::io::Error>| ok(()));
let r = test_future(f);
match r {
Ok(x) => println!("{:?}", x),
Err(_) => println!("error"),
}
}
答案 0 :(得分:0)
extern crate tokio; // 0.1.11
use tokio::prelude::*;
// a future which returns a Vec<String>
fn makes_strings() -> impl Future<Item = Vec<String>, Error = ()> {
future::ok(vec![])
}
fn make_new_string(el: String) -> impl Future<Item = String, Error = ()> {
future::ok(el + "-ok")
}
fn iterate_over() -> impl Future<Item = Vec<String>, Error = ()> {
makes_strings().and_then(|v| {
// iterate over this
let strings = v.into_iter();
// give the values to another future
let futures = strings.map(make_new_string);
// The complete thing should be a future
future::join_all(futures)
})
}