如何从向量创建一个非消耗性迭代器

8

情况:

我有这样一种情况,我想在函数参数上调用一些定义在Iterator特性上的方法。我想要调用它的函数接受一个名为VecLiketrait类型参数。该函数名为get_all_matching_rules

get_all_matching_rules可以接收一个Vec或者另外一个类似自制类型的参数,后者也实现了Iterator。当然这两个都实现了VecLike。我考虑在VecLike上添加一个函数,使其返回一个Iterator,以便在get_all_matching_rules中使用它。

如果我的参数名为:matching_rules,那么我就可以这样做:matching_rules.iter().filter(.

问题:

如何从Vec中返回一个非消费性迭代器?

我想能够在类型为Iterator<T>Vec<T>上返回一个非消费性迭代器。我不想通过调用.iter()来迭代项目。

如果我有(其中self是一个Vec):

fn iter<'a>(&'a self) -> Iterator<T> {
    self.iter()
}

I get the following error:

error: mismatched types: expected `core::iter::Iterator<T>+'a`, found `core::slice::Items<'_,T>` (expected trait core::iter::Iterator, found struct core::slice::Items)

我希望返回 Iterator<t>。如果有比返回 Iterator 更好的方法,欢迎提出。


我已经修改了我的问题,因为之前表述不够清楚。非常抱歉,这完全是我的错。如果还有需要改进的地方,请告诉我。 - Gilles
迭代器是一个trait,你不能直接返回它。你可以返回Box<Iterator<T>>或者U,其中U必须实现Iterator<T>。 - Manishearth
(还不清楚返回Items有什么问题。) - Manishearth
2个回答

9

{{link1:.iter()[T] 上,Vec<T> 会自动解引用,以引用的方式获取 self,并生成一个实现了 Iterator<&T> 的类型。请注意,返回类型不是 Iterator<&T>Iterator 是一个由具体类型实现的 trait,在这种情况下,具体类型 Items<T> 是返回类型,而不是 Iterator<&T>。目前还没有一种语法可以仅指定一个实现它的 trait 作为返回类型,尽管已经提出了 impl Iterator<&T> 语法。

现在你希望实现Iterator<T>而不是Iterator<&T>。 在Rust的内存模型下,每个对象都只属于一个东西,这是不可能使用相同的对象实现的;必须有一些约束条件允许你从&T中获取新的T。 有两种常见的解决方案:
  1. 实现了Copy 特性的类型,可以按位复制。给定一个实现了 Iterator<&T> 的类型变量,其中 TCopy,可以写成 .map(|&x| x).map(|x| *x)(两者等效)。

  2. 实现了Clone 特性的任何类型,在不考虑 Copy 限制的情况下,都可以使操作有意义。给定一个实现了 Iterator<&T> 的类型变量,其中 TClone,可以写成 .map(|x| x.clone())

因此,对于向量 vv.iter().map(|x| x.clone())。通用地,类似这样:

fn iter<T: Clone>(slice: &[T]) -> Map<&T, T, Items<T>> {
    slice.iter().map(|x| x.clone())
}

0

我不确定你在这里询问的是什么。

.iter() 创建了一个迭代器 (Items),它不会移动 Vec (您将得到一个对 &T 的迭代器)。

Filter(和大多数其他迭代器适配器)都是惰性的。也许在过滤它们之前,你应该 chain() 两个迭代器?

否则,如果你不想让 Filter 被消耗掉,就克隆它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接