gpt4 book ai didi

types - Rust中itertools::process_results()的回调类型签名应该是什么?

转载 作者:行者123 更新时间:2023-12-03 11:36:59 29 4
gpt4 key购买 nike

为了逐行解析一个大文件,我试图以以下方式使用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的签名不满意,并说了一些类似的内容

error[E0631]: type mismatch in function arguments

expected signature of 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的类型?

最佳答案

Since ProcessResults implements Iterator, I don't understand the problem here.


问题不在于特征范围,而在于 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());
如果要构建一个新的迭代器,当现有的迭代器遇到错误时该迭代器将停止,则您将无法使用 process_results()。相反,您将需要将 take_while scan 与某些外部状态一起使用,如 here所述。应用于您的代码后, scan的用法如下:
fn parse_file() -> Result<(), Box<dyn std::error::Error>> {
let reader = BufReader::new(File::open("file")?);
let mut err = Ok(());
let line_iter = reader.lines().scan(&mut err, until_err);
let new_iter = filter_lines(line_iter)
// some processing, e.g.:
new_iter.for_each(|line| todo!());
err?; // check whether iteration was ended by error Result
unimplemented!()
}

// filter_lines as originally written...

// helper function for `Iterator::scan()`
fn until_err<T, E>(err: &mut &mut Result<(), E>, item: Result<T, E>) -> Option<T> {
match item {
Ok(item) => Some(item),
Err(e) => {
**err = Err(e);
None
}
}
}

关于types - Rust中itertools::process_results()的回调类型签名应该是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63939234/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com