我正在观看a video on Rust iterators,视频主持人实现了一个稍微复杂的结构Flatten
。本质上,此Flatten
结构包含项,每个项都实现了IntoIterator
特性,以便Flatten
内的每个项(请注意,以下代码不是来自视频,仅用于显示我的困惑):
pub struct Flatten<O>
{
outer: O,
}
impl<O> Flatten<O> {
fn new(iter: O) -> Self {
Flatten { outer: iter }
}
}
然后是Flatten
实现Iterator
特性的部分:
impl<O> Iterator for Flatten<O>
where
O: Iterator,
O::Item: IntoIterator,
{
type Item = <O::Item as IntoIterator>::Item;
fn next(&mut self) -> Option<Self::Item> {
self.outer.next().and_then(|inner| inner.into_iter().next())
}
}
我非常困惑的是,当我们设置约束O::Item: IntoIterator
时,我们显然意味着泛型O
具有实现IntoIterator
的项目。
编辑1:为了澄清,我的困惑是我们首先说了O::Item: IntoIterator
,然后再次指定了type Item = <O::Item as IntoIterator>::Item
。 Item
出现在这两个子句中是指不同的概念吗?
编辑2:我想我现在明白了。 Iterator
有Item
,所以我们可以写O::Item: IntoIterator
。并且,当我们定义type Item = <O::Item as IntoIterator>::Item
时,我们将为Flatten
而不是O
指定返回项目类型。我对语法感到困惑,并有些不了解。
答案 0 :(得分:2)
Rust知道要选择什么项目,因为我们特别告诉他要选择什么Item
。
我们知道Iterator
和IntoIterator
都定义了Item
。
因此Flatten
是其他IntoIterator
(O
)的集合,作为访问此IntoIterator内部项目的目标,我们需要将Flatten::Item
设置为相同作为内部IntoIterator::Item
,因此:
type Item = <O::Item as IntoIterator>::Item;
由于我们正在实现Iterator
,因此Self::Item
是实现定义的项(我们刚刚解释的内部项)。
回顾:
O::Item
=>内部IntoIterator::Item
用于展平Self::Item
=>展平为迭代器Item
。与上一个相匹配。Flatten::Item
=>与Self::Item
实现的Iterator
相同。