【问题标题】:How to fix lifetime mismatch when implementing Iterator Trait?实现迭代器特征时如何修复生命周期不匹配?
【发布时间】:2021-05-06 08:37:14
【问题描述】:

我目前正在练习学习 Rust 语言。我的新挑战是使用存储工具 Iterator Trait 到我的数据结构,其作用是在 Vec<String> 上使用内部迭代器:

impl<'a> CSVReader<'a> {

    pub fn new(lines: Vec<String>, nb_labels: u32, labels: Vec<String>, delim: char) -> Self {
        CSVReader {
            lines,
            iter: None,
            delim,
            nb_labels,
            labels
        }
    }
    
    fn update_iter(&'a mut self) {
        match &self.iter {
            Some(_) => (),
            None => { self.iter = Some(self.lines.iter()) }
        };
    }

    // ...
}

impl<'a> Iterator for CSVReader<'a> {
    type Item = Vec<String>;

    fn next(&mut self) -> Option<Self::Item> {
        self.update_iter();       // ------- line 66
        
        let line: String;
        if let Some(iter) = &mut self.iter {
            line = iter.next()?.clone();
            let cols: Vec<String> = line
            .split(self.delim)
            .map(|x| x.to_string())
            .collect();
            Some(cols)
        } else {
            None
        }    
    }

}

由于此错误,此代码无法编译:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/csv_parser/reader.rs:66:14
   |
66 |         self.update_iter();

我试图在 Iterator Trait 的实现上增加生命周期精度,但我收到另一个错误,要求我使用 next() 函数的正确原型。

我希望你能帮助我理解为什么它不起作用并提供一些解决方案来解决它:)

【问题讨论】:

标签: rust iterator traits lifetime


【解决方案1】:

您正在尝试创建一个自引用结构——其中一个字段引用另一个。做到这一点很难,但并非不可能。开始时最好避免使用自引用结构,无论哪种方式,您都应该谨慎使用它们。

我可以看到以下解决方案:

  • 使用拥有基础向量的迭代器,vec.into_iter()
  • 存储索引而不是指针
    • 请注意,当代码受内存限制时,这对性能几乎没有影响。
  • 使用rental crate 创建一个自引用结构。

【讨论】:

  • 请不要推荐出租的箱子,因为它是(可悲的)no longer maintained or supported
  • @user4815162342 你能推荐一个维护和支持的替代方案吗?
  • 似乎维护了一个列表here,尽管我个人不能推荐任何替代品,因为我没有使用过它们。租赁似乎是最先进的,但我有一种预感,它不会无缘无故地拔掉插头。
猜你喜欢
  • 1970-01-01
  • 2015-11-15
  • 1970-01-01
  • 1970-01-01
  • 2020-07-26
  • 2020-07-26
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
相关资源
最近更新 更多