digitalmars.D.learn - An input range iteration question
- ref2401 (29/29) Apr 08 2015 If Iterator is a struct then Iterator.input won't be adjusted
- Adam D. Ruppe (10/10) Apr 08 2015 A struct is copied when you pass it to foreach, so it iterates
If Iterator is a struct then Iterator.input won't be adjusted
properly when the foreach loop ends.
Iterator.input still holds "abcde" value.
If i mark Iterator as class then Iterator.input will be an empty
string after the foreach loop.
Could anyone explain me the difference please?
Thank you.
struct Iterator {
string input;
this(string input) {
this.input = input;
}
bool empty() { return input.empty; }
dchar front() { return input.front; }
void popFront() {
if (empty) {
return;
}
input.popFront();
writeln("(iterator.popFront)", input);
}
}
void main(string[] args) {
Iterator iterator = Iterator("abcde");
foreach (dchar c; iterator) {
writefln("%s", c);
}
writefln("(the end): %s", iterator.input);
}
Apr 08 2015
A struct is copied when you pass it to foreach, so it iterates over the copy leaving the original the same. A class is referenced by foreach, so the original is affected by it. This is one reason why separating containers from the ranges/iterators that go over them is helpful: the iterator looks at, but doesn't modify the container. When it is done as a separate struct, this typically works fairly easily (unless the act of iterating the container is destructive, like reading from a pipe...)
Apr 08 2015








"Adam D. Ruppe" <destructionator gmail.com>