2016-04-15 1 views
1

Я пытаюсь создать признак итератора, который предоставляет определенный тип ресурса, поэтому я могу реализовать несколько типов источников. Я хотел бы создать источник для чтения из файла CSV, двоичный и т.д ..переменная недолго сохраняется при хранении csv :: DecodedRecords iterator

Я использую rust-csv библиотеку для десериализации CSV данных: Я не могу

#[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 
     } 
    } 
} 

сохранить ссылку к DecodedRecords итератору, возвращенному читатель CSV из-за пожизненные проблемы:

error: reader does not live long enough

Как я могу сохранить ссылку на декодированного записей итератора и что я делаю не так?

ответ

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 непосредственно в CSVBarSource:

struct CSVBarSource { 
    reader: csv::Reader<std::fs::File>, 
} 

И называют decode только по мере необходимости.

+0

Спасибо за четкое объяснение! –