I'm trying to create an iterator trait that provides a specific type of resource, so I can implement multiple source types. I'd like to create a source for reading from a CSV file, a binary etc..
I'm using the rust-csv
library for deserializing CSV data:
#[derive(RustcDecodable)]
struct BarRecord {
bar: u32
}
trait BarSource : Iterator {}
struct CSVBarSource {
records: csv::DecodedRecords<'static, std::fs::File, BarRecord>,
}
impl CSVBarSource {
pub fn new(path: String) -> Option<CSVBarSource> {
match csv::Reader::from_file(path) {
Ok(reader) => Some(CSVBarSource { records: reader.decode() }),
Err(_) => None
}
}
}
impl Iterator for CSVBarSource {
type Item = BarRecord;
fn next(&mut self) -> Option<BarRecord> {
match self.records.next() {
Some(Ok(e)) => Some(e),
_ => None
}
}
}
I cannot seem to store a reference to the DecodedRecords
iterator returned by the CSV reader due to lifetime issues:
error: reader does not live long enough
How can I store a reference to the decoded records iterator and what am I doing wrong?
答案 0 :(得分:2)
根据文件,Reader::decode
is defined as:
fn decode<'a, D: Decodable>(&'a mut self) -> DecodedRecords<'a, R, D>
reader.decode()
reader
不能超过'a
(因为struct CSVBarSource {
records: csv::DecodedRecords<'static, std::fs::File, BarRecord>,
// ^~~~~~~
}
)。
并通过此声明:
reader
'static
需要一个reader
生命周期,也就是说它需要永远存在,因此它不会因此而导致错误“reader
活得不够长。” / p>
您应该将CSVBarSource
直接存储在struct CSVBarSource {
reader: csv::Reader<std::fs::File>,
}
:
decode
仅在需要时致电getCurrentPosition
。