简体   繁体   中英

What is the Item in a nested struct that implements the Iterator trait?

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.

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