【问题标题】:Lifetime issue when implementing Iterator实现迭代器时的生命周期问题
【发布时间】:2015-11-15 16:25:39
【问题描述】:

我正在为几个结构实现Iterator 特征并遇到了一些问题。为什么为Rows 实施Iterator 会显示错误? 这是一个链接:link to playground

基本上为什么这不起作用?

struct Stripe<'a> {
    cells: &'a [u32],
}

struct Rows<'a> {
    foo: &'a Foo,
    vec: Vec<u32>,
    first: bool,
}

impl<'a> std::iter::Iterator for Rows<'a> {
    type Item = Stripe<'a>;
    fn next(&mut self) -> Option<Stripe<'a>> {
        if self.first {
            self.first = false;
            Some(
                Stripe {
                    cells: &self.vec[0..1],
                }
            )
        } else {
            None
        }
    }
}

【问题讨论】:

  • 好的,谢谢,我试试
  • 并确保您的代码是MCVE。您应该能够删除与您的问题不直接相关的所有绒毛。
  • 所以我重用了我的代码,这样可读性够吗?
  • 几乎,Foo 类型和字段与此问题无关,是 imo 混淆的根源

标签: iterator rust lifetime


【解决方案1】:

Row 类型中的生命周期'a 仅指该类型的一个字段。您返回的引用与该生命周期无关。 Iterator 特征不允许您将生命周期返回到迭代器对象本身。这需要为 next 函数添加一个新的生命周期。

我建议您创建一个 RowsIterator 类型并引用您的 Rows 对象并在其中处理特定于迭代器的内容:

struct Stripe<'a> {
    cells: &'a [u32],
}

struct Rows {
    vec: Vec<u32>,
}

struct RowsIter<'a> {
    rows: &'a Rows,
    first: bool,
}

impl<'a> std::iter::Iterator for RowsIter<'a> {
    type Item = Stripe<'a>;
    fn next(&mut self) -> Option<Stripe<'a>> {
        if self.first {
            self.first = false;
            Some(
                Stripe {
                    cells: &self.rows.vec[0..1],
                }
            )
        } else {
            None
        }
    }
}

playground中的完整示例

【讨论】:

  • 谢谢,您的解释有帮助。但是我还是有一个问题,因为我其实需要 Foo 类型,不过我想我自己可以应付。
  • 感谢您提供完整的示例,一开始没有注意到。
  • 您实际上可以将Rowsfoo 引用的生命周期和RowsIterrows 引用的生命周期分开,但很可能您不需要这样做。在完整示例中,我只是为两者使用了相同的生命周期。有关生命周期不同的示例,请参见此处:is.gd/hb09uj
  • 再次感谢。也许您可以查看这段代码并解释为什么 Foo 的实现有效,但它不适用于 FooMut?链接:[is.gd/5sCMHV]
  • 因为如果你调用next 两次,你最终会得到两个对同一个对象的可变引用
猜你喜欢
  • 2020-07-26
  • 2020-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-25
相关资源
最近更新 更多