我是否错误地实现了 IntoIterator 作为参考,或者这是一个应该报告的 Rust bug?

2024-05-17

进一步深化实施示范IntoIterator对于包裹向量铁锈书 https://doc.rust-lang.org/std/iter/trait.IntoIterator.html,我也在努力实现 IntoIterator 供参考到包装纸,按照:

struct VecWrapper(Vec<i32>);

impl VecWrapper {
    fn iter(&'static self) -> Iter {
        Iter(Box::new(self.0.iter()))
    }
}

struct Iter(Box<Iterator<Item = &'static i32>>);

impl Iterator for Iter {
    type Item = &'static i32;
    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}

impl IntoIterator for &'static VecWrapper {
    type Item = &'static i32;
    type IntoIter = Iter;
    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

fn main() {
    // let test = vec![1, 2, 3]; // obviously, works
    let test = VecWrapper(vec![1, 2, 3]); // not working
    for v in &test {
        println!("{}", v);
    }
}

尽管实现可以编译,但尝试在main没有出现以下错误:

error[E0597]: `test` does not live long enough
  --> src/main.rs:31:14
   |
31 |     for v in &test {
   |              ^^^^^
   |              |
   |              borrowed value does not live long enough
   |              argument requires that `test` is borrowed for `'static`
...
34 | }
   | - `test` dropped here while still borrowed

这段代码大大简化了我实际想要使用的内容,仅使用'static生命周期,使用现有的包含类型,并使用i32对于内部(迭代)类型,但它被归结为仅显示问题。


接受的答案解决了问题的第一部分,即不使用'static并使用+ 'a有特点。我对实际代码仍然有疑问,这是一个LazyList执行。我已将其发布为我是否错误地实现了 IntoIterator 以引用 LazyList 实现,或者这是一个 Rust bug? https://stackoverflow.com/questions/40687955/am-i-incorrectly-implementing-intoiterator-for-a-reference-to-a-lazylist-impleme.


您已经正确实现了迭代器以引用VecWrappers that 直播整个节目时间 — the 'static寿命。

您很可能希望拥有一个通用的一生。然后,将为每个实例提供一个具体的生命周期,该生命周期是唯一的。通常,我们很懒,只是给这一生起个名字'a:

struct VecWrapper(Vec<i32>);

impl VecWrapper {
    fn iter(&self) -> Iter {
        Iter(Box::new(self.0.iter()))
    }
}

struct Iter<'a>(Box<dyn Iterator<Item = &'a i32> + 'a>);

impl<'a> Iterator for Iter<'a> {
    type Item = &'a i32;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}

impl<'a> IntoIterator for &'a VecWrapper {
    type Item = &'a i32;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

fn main() {
    let test = VecWrapper(vec![1, 2, 3]);
    for v in &test {
        println!("{}", v);
    }
}

重要变化:

  • Box<dyn Iterator<Item = &'a i32> + 'a> - + 'a加入。这是需要的,因为特质对象将假设不存在引用任何短生命周期的内部值。
  • The Item类型是现在&'a i32.
  • 通用生命周期在许多地方声明并在许多其他地方提供(<'a>).

也可以看看:

  • 为什么需要使用加号运算符 (Iterator + 'a) 为特征添加生命周期? https://stackoverflow.com/q/42028470/155423

通常,没有理由在这里使用特征对象。我只是直接嵌入迭代器:

struct Iter<'a>(std::slice::Iter<'a, i32>);

这避免了需要任何间接,无论如何在这种情况下都不会使用。此外,它更明显地结合了生命周期。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我是否错误地实现了 IntoIterator 作为参考,或者这是一个应该报告的 Rust bug? 的相关文章

随机推荐