iterator - 如何编写返回对自身的引用的迭代器?

标签 iterator rust lifetime

我无法表达Iterator 实现的返回值的生命周期。如何在不更改迭代器返回值的情况下编译此代码?我希望它返回一个引用向量。

很明显,我没有正确使用生命周期参数,但在尝试了各种方法后我放弃了,我不知道该怎么做。

use std::iter::Iterator;

struct PermutationIterator<T> {
    vs: Vec<Vec<T>>,
    is: Vec<usize>,
}

impl<T> PermutationIterator<T> {
    fn new() -> PermutationIterator<T> {
        PermutationIterator {
            vs: vec![],
            is: vec![],
        }
    }

    fn add(&mut self, v: Vec<T>) {
        self.vs.push(v);
        self.is.push(0);
    }
}

impl<T> Iterator for PermutationIterator<T> {
    type Item = Vec<&'a T>;
    fn next(&mut self) -> Option<Vec<&T>> {
        'outer: loop {
            for i in 0..self.vs.len() {
                if self.is[i] >= self.vs[i].len() {
                    if i == 0 {
                        return None; // we are done
                    }
                    self.is[i] = 0;
                    self.is[i - 1] += 1;
                    continue 'outer;
                }
            }

            let mut result = vec![];

            for i in 0..self.vs.len() {
                let index = self.is[i];
                result.push(self.vs[i].get(index).unwrap());
            }

            *self.is.last_mut().unwrap() += 1;

            return Some(result);
        }
    }
}

fn main() {
    let v1: Vec<_> = (1..3).collect();
    let v2: Vec<_> = (3..5).collect();
    let v3: Vec<_> = (1..6).collect();

    let mut i = PermutationIterator::new();
    i.add(v1);
    i.add(v2);
    i.add(v3);

    loop {
        match i.next() {
            Some(v) => {
                println!("{:?}", v);
            }
            None => {
                break;
            }
        }
    }
}

( Playground link )

error[E0261]: use of undeclared lifetime name `'a`
  --> src/main.rs:23:22
   |
23 |     type Item = Vec<&'a T>;
   |                      ^^ undeclared lifetime

最佳答案

据我了解,您希望迭代器将引用向量返回到自身中,对吗?不幸的是,这在 Rust 中是不可能的。

这是修剪下来的 Iterator特点:

trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Item>;
}

请注意,&mut self 之间没有生命周期连接Option<Item> .这意味着 next()方法不能返回对迭代器本身的引用。您只是无法表达返回的引用的生命周期。这基本上就是您找不到指定正确生命周期的方法的原因 - 它看起来像这样:

fn next<'a>(&'a mut self) -> Option<Vec<&'a T>>

除了这不是一个有效的 next() Iterator 的方法特质。

这样的迭代器(可以将引用返回到自身的迭代器)称为流式迭代器。您可以找到更多 here , herehere , 如果你愿意的话。

更新。但是,您可以从迭代器返回对某些其他结构的引用 - 这就是大多数集合迭代器的工作方式。它可能看起来像这样:

pub struct PermutationIterator<'a, T> {
    vs: &'a [Vec<T>],
    is: Vec<usize>
}

impl<'a, T> Iterator for PermutationIterator<'a, T> {
    type Item = Vec<&'a T>;

    fn next(&mut self) -> Option<Vec<&'a T>> {
        ...
    }
}

注意生命周期'a现在在 impl 上宣布堵塞。这样做是可以的(实际上是必需的),因为您需要在结构上指定生命周期参数。然后你可以使用相同的'a都在 Itemnext()返回类型。同样,这就是大多数集合迭代器的工作方式。

关于iterator - 如何编写返回对自身的引用的迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57565919/

相关文章:

java - 使 ArrayList<LinkedList<String>> 成为可迭代对象

lua - 有没有办法告诉 `next` 从特定键开始?

javascript - 在 javascript 中,从迭代器创建数组

c++ - 管理 InputIterator 和 OutputIterator 的 `operator*` 返回值的常量性的规则是什么?

rust - 如何在 Diesel 中为自定义字段类型实现可查询和可插入?

rust - 猜谜游戏,阴影猜测绑定(bind)时出错

rust - 更高等级的生命周期和泛型表现不佳

rust - Clone::clone_from 如何避免不必要的分配?

rust - 添加到基于 RefCell 构建的二叉树时,借用的值不会存在足够长的时间

rust - 从 rust-xcb 调用 "does not live long enough"时出现 `roots` 错误