如何从Vector创建非消耗迭代器

时间:2014-11-16 03:02:28

标签: rust

情况:

我有一种情况,我想在函数参数上调用Iterator特征上定义的某些方法。我想要调用它的函数是使用一个trait类型的参数VecLike。该函数称为get_all_matching_rules

get_all_matching_rules可以接收Vec或其他类似的自制类型,该类型也会实现Iterator。当然,这两个都实现了VecLike。我想在VecLike上添加一个函数让它返回Iterator,以便我可以在get_all_matching_rules中使用它。

如果我的参数命名为:matching_rules,我可以matching_rules.iter().filter(

问题:

如何从Vec

返回非消费迭代器

我希望能够在Vec<T>类型Iterator<T>上返回非消费迭代器。我不打算通过调用.iter()迭代这些项目。

如果我有(自我是Vec):

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

我收到以下错误:

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,那我就是全部的耳朵。

2 个答案:

答案 0 :(得分:8)

Vec<T> Iterator<&T> Iterator<&T>自动解引用,通过引用获取自身并生成实现Iterator的类型。请注意,返回类型为 not Items<T>; Iterator<&T> trait ,它是由具体类型实现的,具体类型impl Iterator<&T>是这种情况下的返回类型,而不是Iterator<T>。目前没有任何语法可以将返回类型指定为由它实现的特征,尽管已经建议使用语法Iterator<&T>

现在您希望实现T而不是&T。在Rust的内存模型中,每个对象只有一个东西,这是不可能的具有相同的对象;必须有一些约束才能让您从Iterator<&T>获得新的T。有两个容易提供的解决方案:

  1. .iter() on [T]特征,适用于可以按位复制的类型。给定Copy .map(|&x| x) .map(|x| *x) Copy类型的变量,可以写成Iterator<&T>T(两者是等价的)。

  2. Copy特征,适用于任何可以使操作有意义的类型,无论Clone边界如何。给定.map(|x| x.clone()) v v.iter().map(|x| x.clone()) fn iter<T: Clone>(slice: &[T]) -> Map<&T, T, Items<T>> { slice.iter().map(|x| x.clone()) } 类型的变量,可以写成{{1}}。

  3. 因此,给定一个向量{{1}},{{1}}。通常,这样的事情:

    {{1}}

答案 1 :(得分:0)

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

.iter()会创建一个迭代器(Items),它不会移动Vec(你会在&T之上得到一个迭代器)。

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

否则,如果您不希望消费Filter,请将其克隆。