4

I have a struct called Library, which has a vector of strings (titles). I have implemented an iterator for this. Here is my code.

#[derive(Debug, Clone)]
struct Library {
    books: Vec<String>
}

impl Iterator for Library {
    fn next(&mut self) -> Option<Self::Item> {
        ...
    }
}

Now, I am trying to implement an Iterator using a trait, like this:

fn foo(x: Vec<u32>) -> impl Iterator<Item=u32> {
    //Unsure if correct method
    fn next() -> Option<...> {
       x.into_iter()....

    }
}

But I'm unsure of how to proceed in this case. Do I simply have to define a next() method again? That doesn't seem to be the case, according to other resources. Why is that? Shouldn't an iterator (which is being returned) have a next() method?

What is the general method for implementing an iterator this way?

1

1 Answer 1

8

You wouldn't implement the trait directly on Library. The library is not an iterator, but it is something that could be iterated by an iterator.

Instead, just declare a method that returns an iterator, and you can simply return an iterator directly from your vector. There is no need for a custom iterator implementation. For example:

impl Library {
    fn iter(&self) -> impl Iterator<Item=&String> {
        self.books.iter()
    }
}

For your second case, you can turn the vector into an iterator using into_iter(), provided by the IntoIterator trait:

fn foo(x: Vec<u32>) -> impl Iterator<Item=u32> {
    x.into_iter()
}
Sign up to request clarification or add additional context in comments.

6 Comments

Right, so the .into_iter() I understand. What if I had a more complicated type? Such as fn foo<A>(x: Vec<A>) -> impl Iterator<Item = (u32,A)>? I want the iterator to go through each element in x and return (0,A) or (1, A) based on some condition?
Similarly, what if I had fn foo(x: Vec<u32>) -> impl Iterator<Item = (u32, u32)>?
@DarrelGulseth That's where the standard iterator utilities like .map() come in. So you could do x.into_iter().map(|v| /* some expression here */)
@DarrelGulseth It all depends how you want to iterate that. If you want to flatten the nested vector into one iterator of u32 then you just do x.into_iter().flatten().
@DarrelGulseth No problem. The Iterator trait provides dozens of such utilities. Using them you can do just about any sequence manipulation you can think of. It's very rare you need to implement your own iterator, unless you are implementing something like a paged API client or are implementing your own data structure from scratch.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.