I am watching a video on Rust iterators and the video host implements a slightly more complex struct Flatten
. In essence, this Flatten
struct holds items, each of which implements the IntoIterator
trait so that each item inside Flatten
( Note that the following code is not the final code from the video and is only used to show my confusion ):
pub struct Flatten<O>
{
outer: O,
}
impl<O> Flatten<O> {
fn new(iter: O) -> Self {
Flatten { outer: iter }
}
}
Then there is the part where Flatten
implements the Iterator
trait:
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())
}
}
What I am very confused about is that when we set the constraint O::Item: IntoIterator
, we obviously meant that the generic type O
has items that implement IntoIterator
.
Edit 1: To clarify, my confusion was that we first said that O::Item: IntoIterator
and then specified again type Item = <O::Item as IntoIterator>::Item
. Are the Item
s appearing in these two clauses referring to different concepts?
Edit 2: I think I understand it now. An Iterator
has Item
, so we could write O::Item: IntoIterator
. And when we define type Item = <O::Item as IntoIterator>::Item
, we are specifying the return Item type for Flatten
, not for O
. I was confused by the syntax and had some illogical understanding.
Rust knows what item to chose because we specifically tell him what Item
to chose. We know that both Iterator
and IntoIterator
define an Item
.
So Flatten
is a collection of other IntoIterator
( O
) , being the target to access this IntoIterator inner items we need to set the Flatten::Item
to be the same as the inner IntoIterator::Item
, hence:
type Item = <O::Item as IntoIterator>::Item;
Since we are implementing Iterator
the Self::Item
is that implementation-defined item (the inner ones that we just explained).
As recap:
O::Item
=> Inner IntoIterator::Item
for flatten Self::Item
=> Flatten as Iterator Item
. Which matches the previous one.Flatten::Item
=> Same as Self::Item
for the Iterator
implementation.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.