Understanding Iterators in Rust
As often as I’ve used a .repeat(), .map(), or a .forEach(), I’ve never really considered the mechanisms that make these iterations possible. The underlying code that language built-ins or libraries use to iterate is standardized, and I’ve always trusted it so deeply I’ve never spent the energy to see how it really works.
That’s changing now!
The Standard Iterator
Is very clean. I’ll cover traits more later, but it’s basically an interface. If you’re not familiar with interfaces, here’s my quick description. It’s a way of defining properties and method requirements for instances of a given class. Traits appear to be quite similar.
Here is an excerpt from the docs:
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
…
Iterator’s full definition includes a number of other methods as well, but they are default methods, built on top ofnext
, and so you get them for free.
…
What does this mean?
It means that you have the power to determine whether or not any specific struct is iterable or not.
I think what’s interesting about this is the act of iteration is being abstracted away from specific ‘objects’ in the language. The responsibility of iteration does not belong to an array, or a list, etc.
This means the user can determine which objects in their code are capable of iteration. The need of structuring a program around objects which happen to be capable of iteration is not a requirement. And it’s memory is managed by the Rust compiler.
This might be a pivotal moment for me in starting to really love using Rust.
This explains why there are so many ‘iter’ results from the rust library
So many objects already have iterators built in. This makes sense because collections are probably one of the most common patterns in programming. And when you have collections the ability to index and ‘iterate’ them is usually needed to do the algorithmic location of individual entities within that specific collection.
Very cool
Now I must admit I’m curious to see if I can’t implement iterators onto type definitions in other languages! Perhaps this isn’t a power that’s limited to Rust. I do imagine that the practice is frowned upon. I know that as a professional in OOP there is something nice about the comfort of standard practices when reading OPC (Other Peoples Code) that gives me comfort.
Conclusion
My understanding of Iterators, or more abstractly, the act of iteration has improved through this exercise. I now see iteration as little more than being able to distinguish relationships between individual entities in memory from a specific entry point. I was viewing it more as finding a property within an object. As if somehow the object was responsible for the memory and not the compiler or the interpreter. This was a passively held viewpoint, as I had never really considered it before.
This is specifically why I began doing this challenge. I know that understanding Rust deeply will improve my understanding across the board.
No homework this time!