我正在尝试创建一个提供特定类型资源的迭代器特征,因此我可以实现多种源类型。我想创建一个源来读取 CSV 文件、二进制文件等。
我正在使用 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
}
}
}
由于生命周期问题,我似乎无法存储对 CSV 阅读器返回的 DecodedRecords
迭代器的引用:
error: reader does not live long enough
我如何存储对解码记录迭代器的引用以及我做错了什么?
最佳答案
根据文档,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
。
关于csv - 存储 csv::DecodedRecords 迭代器时变量的生命周期不够长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36645452/