这可能是Rust 的一个超级基本方面,但我正在努力看透参考判断的级别,以使其有意义.
假设我当前的程序对文件中所有二进制编码的整数求和:
pub fn read_int(file: &mut File) -> io::Result<i64> {
let mut int_buffer = [0; 8];
file.read_exact(&mut int_buffer)?;
Ok(i64::from_be_bytes(int_buffer))
}
fn read_loop() -> io::Result<f64> {
let mut file = File::open("data.dat")?;
let mut found_end = false;
let mut dat_sum = 0;
let mut dat_count = 0;
while !found_end {
match read_int(&mut file) {
Ok(d) => {
dat_sum += d;
dat_count += 1;
},
Err(_) => found_end = true
};
}
Ok(dat_sum as f64 / dat_count as f64)
}
我想对此进行抽象,以使用专门的i64
迭代器:
fn read_loop() -> io::Result<f64> {
let mut int_iter = IntIterator::open("data.dat")?;
let mut dat_sum = 0;
let mut dat_count = 0;
for d in iiter {
dat_sum += d;
dat_count += 1;
}
Ok(dat_sum as f64 / dat_count as f64)
}
我try 实现此功能,但:
pub struct TickIterator<'r> {
file: &'r mut File,
found_end: bool
}
impl<'r> TickIterator<'r> {
pub fn new(fp: String) -> io::Result<TickIterator<'r>> {
let mut file = File::open(fp)?;
Ok(TickIterator {
file: &mut file,
found_end: false
})
}
}
impl<'a> Iterator for TickIterator<'a> {
type Item = i64;
fn next(&mut self) -> Option<Self::Item> {
if self.found_end {
None
} else {
match read_int(self.file) {
Err(_) => {
self.found_end = true;
None
},
Ok(d) => Some(d)
}
}
}
}
看起来我有很多问题要解决;第一个错误似乎是,我无法在 struct 内返回对file
的引用,因为它属于函数new
本身.
这是正确的方法,还是我在这里做错了?