Concrete implementation of Iterator?

hey, Iterators are all abundent in the standard library. But I'm having strangely hard time finding any structs implementing it. I want something like lazy generator, not like Vector, so basically Iterator, but not trait Iterator instead:

struct Iterator { next: Box<Fn blabla> }

I wouldn't mind defining this exact type in my code if only I could inline the definition inside function definition. I don't want to pass generic dynamic Iterator, because this introduces needless to me type variable, complicating things.

What's wrong with the explicit list of implementing types?

It is unclear what you mean by "generic dynamic". You can have dyn Iterator<Item = ConcreteType> which is type-erased and not generic.

"Iterator but not trait Iterator" doesn't make any sense to me. An iterator in this language is a type that implements the Iterator trait.

Do you want iter::from_fn()?

I'm 99% sure topicstarter wants lending iterator.

Something that generates iterated elements out of thin air but keeps them inside. That's currently not possible in Rust. But Range creates objects and then gives them away. That is possible and easy.

1 Like

If you're looking for an implementation of Iterator that is “concrete” in that you construct it with some items and those are the items it produces, then you want the Vec iterator (which is of type std::vec::IntoIter):

vec![1, 2, 3].into_iter()

If that's not it, some more description (preferably with code) of how you want to use what you're looking for would help.

3 Likes

Hey, thanks the explicit list of implementators is what I was looking for. from_fn is usefull as well.

But dyn Iterator is generic, isn't it? Having it as a struct field introduces a type parameter and this is precisely what I wanted to avoid. I'm thinking if I keep in the struct and I'm going to use single implementation in the end, then really I could just be using concrete Iterator provider.

This is one of those confusing situations where a term has one meaning as technical jargon and a different one in casual speech. When talking about Rust, "generic" usually refers to something that takes a type parameter, e.g. Something<T>, which gets resolved to a specific type at compile time. dyn Iterator is a mechanism for dynamic dispatch, which lets the backing type be determined at runtime— This is "generic" in the casual sense, in that it's code that can work with multiple types, but not in the jargon sense (it uses a completely different mechanism).

5 Likes

I found what I was looking for:
FromFn : FromFn in std::iter - Rust

That is a concrete struct not abstract dyn Iterator, yet it's exactly the same expressive. My reason was that I wanted to include such an Iterator in a struct. Out of the 3 below options I like the third best:

struct A(x: Box<dyn Iterator>)
struct A<T: Iterator>(x: T) // weird that this even works? but cool
struct A(x: FromFn<>)

No. It's type-erased.

What makes you think that? This declaration compiles:

struct MyIter {
    iter: Box<dyn Iterator<Item = String>>,
}

No type parameters in sight.

In order to make this compile, you will need a type parameter for the function too:

struct A<F> { x: FromFn<F> }

If that is acceptable to you, then you can use a parameter for the iterator, as in your second option, and that is strictly more flexible than requiring the use of FromFn. [1]


  1. Technically, you can use a function pointer with FromFn, like struct A { x: FromFn<fn() -> Option<String>> }, but that will be mostly useless because a function pointer can't hold the state of the iterator, so it could only iterate over some static state, or be equivalent to std::iter::empty() or std::iter::repeat(). ↩︎

1 Like

This declaration compiles

oh, yeah, right. I don't remember what I've tried that made me think that - but probably I didn't box the type or something along these lines.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.