情况:
我有一种情况,我想在函数参数上调用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
,那我就是全部的耳朵。
答案 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
。有两个容易提供的解决方案:
.iter()
on [T]
特征,适用于可以按位复制的类型。给定Copy
.map(|&x| x)
.map(|x| *x)
Copy
类型的变量,可以写成Iterator<&T>
或T
(两者是等价的)。
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}}。
因此,给定一个向量{{1}},{{1}}。通常,这样的事情:
{{1}}
答案 1 :(得分:0)
我不确定你在这里问的是什么。
.iter()
会创建一个迭代器(Items
),它不会移动Vec
(你会在&T
之上得到一个迭代器)。
Filter
(以及大多数其他迭代器适配器)都是惰性的。也许在过滤它们之前你应该chain()
两个迭代器?
否则,如果您不希望消费Filter
,请将其克隆。