www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - An input range iteration question

reply "ref2401" <refactor24 gmail.com> writes:
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
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
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