foreach iterator with closure
Ali Çehreli
acehreli at yahoo.com
Sun Jun 28 04:06:00 UTC 2020
On 6/27/20 8:19 PM, Denis wrote:
> Is it possible to write an iterator
It is arguable whether D's ranges are iterators but if nouns are useful,
we call them ranges. :) (Iterators can be written in D as well and then
it would really be confusing.)
> struct letters {
> string str;
> int pos = 0;
> char front() { return str[pos]; }
> void popFront() { pos ++; }
> bool empty() {
> if (pos == 0) writeln(`BEGIN`);
> else if (pos == str.length) writeln("\nEND");
> return pos == str.length; }}
>
> void main() {
> foreach (letter; letters(`hello`)) {
> write(letter, ' '); }
> writeln(); }
>
> The obvious problems with this code include:
>
> (1) The user can pass a second argument, which will set the initial
> value of pos.
That problem can be solved by a constructor that takes a single string.
Your BEGIN code would normally go there as well. And END goes into the
destructor:
struct letters {
this(string str) {
this.str = str;
this.pos = 0; // Redundant
writeln(`BEGIN`);
}
~this() {
writeln("\nEND");
}
// [...]
}
Note: You may want to either disallow copying of your type or write copy
constructor that does the right thing:
https://dlang.org/spec/struct.html#struct-copy-constructor
However, it's common to construct a range object by a function. The
actual range type can be kept as an implementation detail:
struct Letters { // Note capital L
// ...
}
auto letters(string str) {
// ...
return Letters(str);
}
struct Letter can be a private type of its module or even a nested
struct inside letters(), in which case it's called a "Voldemort type".
Ali
More information about the Digitalmars-d-learn
mailing list