variable does not live long enough when storing a csv::DecodedRecords iterator

时间:2016-04-15 11:05:15

标签: csv rust lifetime

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?

1 个答案:

答案 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