What is an iterator in Rust

I know but iterator and cursor in C++ are the same. In rust they are not. Yet iter returns cursor and into_iter turns vector into a iterable range.

Know that there are many kinds of Iterators: https://en.wikipedia.org/wiki/Iterator

Exactly, and first sentence in that article says exactly what I say about what an iterator is.

The iterator returned by vec.iter() is not a fully-featured cursor. Once you've called .next(), you cannot go backwards. A cursor is a more powerful abstraction than an iterator, and Rust only uses iterators for iterators.

Of course, how powerful you make the abstraction is a trade-off. A cursor can do more things than an iterator (e.g. go backwards), but some things can be an iterator and not a cursor, because those things may not have the ability to go backwards (e.g. singly linked list).

To illustrate how all Rust iterators look inside, please check out this example.

2 Likes

No, no, to me it looks like rust has a basic version of an iterator and that's it. The only trade off here is that rust has fewer types of iterators, and thus, it is simpler/easier to use.

It is worth mentioning that Rust has additional traits for more powerful iterators, for example there is the DoubleEndedIterator trait that allows you to remove items from both ends of the iterator.

If an iterator supports that feature, it will implement both the Iterator and DoubleEndedIterator traits.

I'm sorry, but you are mistaken. The next method in those languages' iterators can do anything, just like the next method in Rust. For example, see Enumerable.Repeat in C#.

The documentation says

This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action.

... meaning the elements are generated on demand. It's not a cursor. Here is how it's implemented in the .NET Core source code.

It is not a range; a range is entirely separate concept. Check out the example I posted earlier, which implements an iterator from scratch. It is not a range in any way, it is an iterator consisting of an infinitely repeating value which would be impossible with just a range.

C++ is the only language which implements iterators in the way you think about them.

I suppose you can consider ranges as a special case of the more general concept of an iterator.

1 Like

I disagree. Iterator is (well, in C++) a thing that points to something and can retrieve the value that it points to. Range is a some sort of collection that stores the values that you can point to with an iterator.

To me, the word range would imply something with a known finite length that allows you to access it from both ends.

To me, the word iterator is something that can yield items in a sequence. It doesn't have to point to the things, and can create them on demand if it so wishes. It doesn't have to have a length that is known in advance, or be finite at all.

Then it is more related to a generator than to a cursor. And that's fine. But in C++ iterator is a cursor, pointer that you point with at something and retrieve the value that you are pointing to.

Sure. A Rust iterator is a special case of a generator. There are some iterators that are very cursor-like in the sense that their item type is a reference into a collection, which is why I sometimes use that word as an analogy.

1 Like

I think you are still misunderstanding how rust iterators work. They do not produce all values in advance. The iterator for a Vec looks something like this (not the actual code, but close enough for teaching purposes):

pub struct SliceIter<'a, T>  {
    slice: &'a [T],
    current: usize,
}

impl<'a, T> std::iter::Iterator for SliceIter<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        self.current += 1;
        self.slice.get(self.current - 1)
    }
}

There's no magic. Nothing is calculated in advance.

1 Like

Sure, the example you've provided shows the iterator I am familiar with. But rust has also other types of iterators, that tbh are generators but they are called iterators. Is it OK? Why not. Confusing perhaps, but this is just another language with it's own weirdness's.

You would not consider SliceIter from that example a generator? I certainly would.

To me, generators are things that yield a sequence of items, followed by a completing item that marks the end, often of a different type than the items in the sequence. Iterators are generators with the unit type () as the completing type.

No, I would not consider it a generator. I would consider it a retriever. That iterator doesn't generate anything, it simply retrieves what's already there.

It generates references?

Please... It doesn't generate anything new. It simply retrieves values that are already in vector.

I'm serious. Sequences of stuff is a very useful concept. Why would I arbitrarily limit it to things where the item type is not a reference?

And what does this has to do with price of tomatoes?