kni*_*t42 4 generics iterator traits rust
我想编写一个解析文本的函数,但文本可能来自外部文件或内部文件&str.该parse功能可能如下所示:
fn parse(lines: GenericLinesGenerator) {
   for line in lines {
       // parse content
   }
}
......它可以像这样调用:
use std::io::BufReader;
use std::fs::File;
let fin = BufReader::new(File::open("info.txt").expect("not found"));
parse(TransformFromIO(fin.lines()))
要么
let content: &'static str = "some\nlong\ntext";
parse(TransformFromStr(content.lines()))
是否可以实现这样的parse功能?
这两个迭代器不会产生相同的值:
impl<B: BufRead> Iterator for io::Lines<B> {
    type Item = Result<String>;
}
impl<'a> Iterator for str::Lines<'a> {
    type Item = &'a str;
}
你必须以某种方式处理这种差异.最重要的区别是io::Lines可能会失败.你的程序必须决定如何处理; 我选择了中止该计划.
接下来你需要做的是接受任何可以转换为迭代器的类型,并且必须将迭代器产生的值转换为你可以处理的类型.它似乎&str是共同点.
这通过使用IntoIterator和解决Borrow:
use std::borrow::Borrow;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
fn parse<I>(lines: I)
where
    I: IntoIterator,
    I::Item: Borrow<str>,
{
    for line in lines {
        println!("line: {}", line.borrow());
    }
}
fn main() {
    parse("alpha\nbeta\ngamma".lines());
    println!("----");
    let f = File::open("/etc/hosts").expect("Couldn't open");
    let b = BufReader::new(f);
    parse(b.lines().map(|l| l.expect("Bad line!")));
}
有关特征边界的更多信息,请查看关于子句的Rust编程语言部分.where
| 归档时间: | 
 | 
| 查看次数: | 143 次 | 
| 最近记录: |