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

Types Rust中itertools::process_results()的回调类型签名应该是什么?,types,rust,iterator,Types,Rust,Iterator,为了逐行解析一个大文件,我尝试以以下方式使用它,如果无法读取该文件,它将立即失败: 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);

为了逐行解析一个大文件,我尝试以以下方式使用它,如果无法读取该文件,它将立即失败:

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!()
    })
}
fn parse_file()->结果{
让reader=BufReader::new(文件::打开(“文件”)?);
让line_iter=处理结果(reader.lines(),filter_line);
未执行!()
}
fn filter_行(行:I)->impl迭代器{
行。过滤器(|行|{
未执行!()
})
}
但是,编译器对
过滤器行的签名不满意,并说

错误[E0631]:函数参数中的类型不匹配

for)->的预期签名

由于
ProcessResults
实现了
Iterator
,我不理解这里的问题。 需要如何更改
过滤线的类型才能使用
处理结果

由于
ProcessResults
实现了
Iterator
,我不理解这里的问题

问题不在trait界限内,而是在
filter\u行
返回的值的生命周期内
process\u results
为您提供了一个迭代器,该迭代器引用
process\u results
调用的本地数据。您可以使用该迭代器,例如对其进行迭代或将其传递给函数,但不允许从回调中返回它,也不允许返回引用它的迭代器,就像
filter\u lines()
所做的那样。这是因为回调返回的值是由
process\u results
本身返回的,并且该值不能引用
process\u results
的本地数据

例如,
filter\u lines()
的这个实现通过迭代器返回一个基于内部找到的值的值,编译:

fn filter_lines<I: Iterator<Item = String>>(lines: I) -> Option<usize> {
    lines.map(|line| line.len()).max()
}
// with filter_lines as originally defined
let line_max = process_results(reader.lines(), |lines| filter_lines(lines).max());
如果要构建一个新的迭代器,在现有迭代器遇到错误时停止,则不能使用
process\u results()
。相反,您将需要使用或与某些外部状态一起使用,如上所述。应用于您的代码,
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
        }
    }
}
fn parse_file()->结果{
让reader=BufReader::new(文件::打开(“文件”)?);
让mut err=Ok(());
让line_iter=reader.lines().scan(&mut err,直到_err);
让新iter=过滤线(线iter)
//某些处理,例如:
新的iter.for每个(| line | todo!());
错误?;//检查迭代是否由错误结果结束
未执行!()
}
//按最初写入的方式筛选\u行。。。
//'Iterator::scan()的助手函数`
fn until_err(err:&mut&mut Result,item:Result)->Option{
比赛项目{
Ok(项目)=>部分(项目),
错误(e)=>{
**err=err(e);
没有一个
}
}
}

为了便于实验:奇怪的是,我在不返回迭代器时仍然会遇到一个类型错误:@wonce有趣的是,它只在中间有一个闭包,就像我的回答一样。因此,生命周期实际上是一个更深层次的第二个问题。我假设闭包解决了类型错误,因为它被推断为具有正确的类型,该类型神秘地与
filter\u行
兼容,但不兼容。