【问题标题】:How to create a non consuming iterator from a Vector如何从 Vector 创建非消耗迭代器
【发布时间】:2015-01-13 05:15:36
【问题描述】:

情况:

我有一种情况,我想在函数参数上调用Iterator trait 上定义的一些方法。我想调用它的函数采用类型为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 返回非消耗迭代器?

我希望能够在Iterator<T> 类型的Vec<T> 上返回一个非消耗迭代器。我不想通过调用 .iter() 来迭代这些项目。

如果我有(其中 self 是 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&lt;t&gt;。如果有更好的方法而不是返回Iterator,我会全力以赴。

【问题讨论】:

  • 我已经编辑了我的问题,因为我之前并不清楚。对不起,这完全是我的错。如果我可以进一步改进,请告诉我。
  • (在移动设备上,无法更新答案)迭代器是一个特征,你不能返回它。您可以返回 Box> 或 U where U:Iterator.
  • (另外,还不清楚退货有什么问题。

标签: rust


【解决方案1】:

.iter() on [T]Vec&lt;T&gt; 自动取消引用,通过引用获取 self 并生成实现 Iterator&lt;&amp;T&gt; 的类型。注意返回类型是notIterator&lt;&amp;T&gt;Iterator 是一个由具体类型实现的trait,具体类型Items&lt;T&gt; 在这种情况下是返回类型,而不是Iterator&lt;&amp;T&gt;。目前没有任何语法可以将返回类型仅指定为由它实现的特征,尽管建议使用语法 impl Iterator&lt;&amp;T&gt;

现在您希望实现Iterator&lt;T&gt; 而不是Iterator&lt;&amp;T&gt;。在 Rust 的内存模型中,每个对象都只属于一个事物,这对于相同的对象是不可能的;必须有一些限制才能让您从&amp;T 获得新的T。有两种现成的解决方案:

  1. Copy 特征,用于只能按位复制的类型。给定一个实现Iterator&lt;&amp;T&gt; 类型的变量,其中TCopy,这可以写成.map(|&amp;x| x).map(|x| *x)(两者是等价的)。

  2. Clone 特征,适用于可以使操作有意义的任何类型,无论Copy 边界如何。给定一个实现Iterator&lt;&amp;T&gt; 类型的变量,其中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())
}

【讨论】:

    【解决方案2】:

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

    .iter() 创建一个不会移动 Vec 的迭代器 (Items)(您将在 &amp;T 上获得一个迭代器)。

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

    否则,如果您不想使用 Filter,请克隆它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-15
      • 1970-01-01
      • 2015-09-13
      • 2018-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多