如何解决Rust中itertools :: process_results的回调类型签名应该是什么?
要逐行解析大文件,我试图以以下方式使用itertools::process_results,如果无法读取文件,则会立即使它失败:
fn parse_file() -> Result<(),Box<dyn std::error::Error>> {
let reader = BufReader::new(File::open("file")?);
let line_iter = process_results(reader.lines(),filter_lines);
unimplemented!()
}
fn filter_lines<I: Iterator<Item=String>>(lines: I) -> impl Iterator<Item=String> {
lines.filter(|line| {
unimplemented!()
})
}
但是,编译器对filter_lines
的签名不满意,并说类似
for<'r> fn(itertools::process_results_impl::ProcessResults<'r,std::io::Lines<std::io::BufReader<std::fs::File>>,std::io::Error>) -> _
的预期签名
由于ProcessResults
实现了Iterator
,因此我在这里不明白问题所在。
filter_lines
的类型如何更改才能与process_results
一起使用?
解决方法
由于
[selectedCountryISO]="selectedCountryISO"
实现了ProcessResults
,因此我在这里不明白问题所在。
问题不在于特征范围,而在于Iterator
返回的值的生存期。 filter_lines
会为您提供一个迭代器,该迭代器引用process_results
调用本地的数据。您可以使用该迭代器,例如对其进行迭代或将其传递给函数,但不允许从回调中返回它,也不允许返回引用该迭代器的迭代器,例如process_results
可以。这是因为从回调返回的值由filter_lines()
本身返回,并且该值不得引用process_results
本地的数据。
例如,process_results
的此实现将遍历迭代器并基于内部找到的值返回一个值,该编译如下:
filter_lines()
同样,保留fn filter_lines<I: Iterator<Item = String>>(lines: I) -> Option<usize> {
lines.map(|line| line.len()).max()
}
的实现,但不从回调返回迭代器,也会编译:
filter_lines
如果您要构建一个新的迭代器,当现有迭代器遇到错误时该迭代器将停止运行,那么您将无法使用// with filter_lines as originally defined
let line_max = process_results(reader.lines(),|lines| filter_lines(lines).max());
。相反,您将需要使用take_while
或scan
并使用一些外部状态,如here所述。应用于您的代码的process_results()
将会这样使用:
scan
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。