简体   繁体   English

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

[英]How to create a non consuming iterator from a Vector

Situation: 情况:

I have a situation where I would like to call some method defined on the Iterator trait on a function parameter. 我有一种情况,我想在函数参数上调用Iterator特征上定义的一些方法。 The function that I would like to call it is taking a parameter of a type which is a trait called VecLike . 我想称之为函数的函数是一个类型的参数,它是一个名为VecLiketrait The function is called get_all_matching_rules . 该函数名为get_all_matching_rules

get_all_matching_rules can receive either a Vec or another similar home made type which also implements Iterator . get_all_matching_rules可以接收Vec或其他类似的自制类型,它也实现了Iterator Of course both of these implement VecLike . 当然,这两者都实现了VecLike I was thinking of adding a function on VecLike to have it return an Iterator so that I could use it in get_all_matching_rules . 我想在VecLike上添加一个函数让它返回一个Iterator这样我就可以在get_all_matching_rules使用它。

If my parameter is named: matching_rules I could then do matching_rules.iter().filter( . 如果我的参数名为: matching_rules ,那么我可以执行matching_rules.iter().filter(

Question: 题:

How do I return a non consuming iterator from a Vec ? 如何从Vec返回非消耗迭代器?

I'd like to be able to return a non consuming iterator on a Vec<T> of type Iterator<T> . 我希望能够在Iterator<T>类型的Vec<T>上返回一个非消耗迭代器。 I am not looking to iterate the items by calling .iter() . 我不打算通过调用.iter()来迭代这些项目。

If I have (where self is a Vec): 如果我有(自我是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)

I would like to return the Iterator<t> . 我想返回Iterator<t> If there is a better way to go at this rather than returning an Iterator , I'm all ears. 如果有更好的方法去做这个而不是返回Iterator ,我全都听见了。

.iter() on [T] , which Vec<T> automatically dereferences to, takes self by reference and produces a type implementing Iterator<&T> . [T]上的.iter()Vec<T>自动解引用,通过引用获取自身并生成实现Iterator<&T>的类型。 Note that the return type is not Iterator<&T> ; 请注意,返回类型不是 Iterator<&T> ; Iterator is a trait which is implemented by concrete types, and the concrete type Items<T> is the return type in that case, not Iterator<&T> . Iterator是一个由具体类型实现的特性 ,具体类型Items<T>在这种情况下是返回类型,而不是Iterator<&T> There is not currently any syntax for specifying a return type merely as a trait that is implemented by it, though the syntax impl Iterator<&T> has been suggested. 目前没有任何语法可以将返回类型仅仅指定为由它实现的特征,尽管已经建议使用语法impl Iterator<&T>

Now you wish something implementing Iterator<T> rather than Iterator<&T> . 现在你希望实现Iterator<T>而不是Iterator<&T> Under Rust's memory model where each object is owned by exactly one thing, this is not possible with the same objects ; 在Rust的内存模型中,每个对象只有一个东西,这对于相同的对象是不可能 ; there must be some constraint to allow you to get a new T from the &T . 必须有一些限制,允许你从&T获得一个新的T There are two readily provided solutions for this: 有两个容易提供的解决方案:

  1. The Copy trait, for types that can just be copied bitwise. Copy特征,适用于可以按位复制的类型。 Given a variable of a type implementing Iterator<&T> where T is Copy , this can be written .map(|&x| x) or .map(|x| *x) (the two are equivalent). 给定一个实现Iterator<&T>的类型的变量,其中TCopy ,这可以写成.map(|&x| x).map(|x| *x) (两者是等价的)。

  2. The Clone trait, for any types where the operation can be caused to make sense, regardless of Copy bounds. Clone trait,适用于可以使操作有意义的任何类型,无论Copy bounds如何。 Given a variable of a type implementing Iterator<&T> where T is Clone , this can be written .map(|x| x.clone()) . 给定一个实现Iterator<&T>的类型的变量,其中TClone ,这可以写成.map(|x| x.clone())

Thus, given a vector v , v.iter().map(|x| x.clone()) . 因此,给定一个向量vv.iter().map(|x| x.clone()) Generically, something like this: 通常,这样的事情:

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

I'm not sure what you're asking here. 我不确定你在这里问什么。

.iter() creates an iterator ( Items ) which does not move the Vec (You'll get an Iterator over &T ). .iter()创建一个不移动Vec的迭代器( Items )(你将获得Iterator over &T )。

Filter (and most other iterator adapters) are lazy. Filter (以及大多数其他迭代器适配器)都是惰性的。 Perhaps you should chain() the two iterators before filtering them? 也许你应该在过滤它们之前chain()两个迭代器?

Otherwise, if you don't want the Filter to be consumed, clone it. 否则,如果您不想使用Filter ,请克隆它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM