rust - 带有类型问题的 Future 和 Stream 嵌套
问题描述
我想使用一个返回 a 的未来,Vec<String>
在未来流中迭代它并将值提供给另一个未来,并且应该处理这个未来的结果。完整的东西也应该是未来。
怎么走?我尝试了不同的方法,但我遇到了类型问题,我不明白。
为什么会有这些嵌套的未来结果类型签名?这不应该成为最终的结果吗?为什么编译器不知道类型?
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]>>, _>) -> _`
我为此设置了一个游乐场
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"),
}
}
解决方案
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)
})
}
推荐阅读
- java - 使用Java Android将base64编码字符串转换为p12文件的正确方法
- codeigniter - 日志文件中的意外 URL - Codeigniter 3 - Monolog
- python - Django - 返回每个没有字段的模型值
- javascript - 带有按钮的文件拖放区(vanilla JS)
- c# - 活动报告:慢速打印请求
- amazon-web-services - 跨节点的卷 (ebs) 附加 pod 分布
- javascript - 使用 vanilla js 从表单中删除行
- android - ViewModel 中 RxJava 主题的单元测试
- javascript - 如何在音频结束后仅触发一次功能,p5.Js/Javascript
- c# - AWS 无服务器应用程序无法添加服务参考 WCf 服务