User defined type and foreach
Mike Parker
aldacron at gmail.com
Fri Nov 17 07:40:35 UTC 2017
On Friday, 17 November 2017 at 03:15:12 UTC, Tony wrote:
>
> Thanks T! Good information, especially "iterating over a range
> is supposed to consume it". I have been reading
> dlang.org->Documentation->Language Reference, but should have
> also read dlang.org->Dlang-Tour->Ranges. Although that page
You might also find use in this article (poorly adapted from
Chapter 6 of Learning D by the publisher, but still readable):
https://www.packtpub.com/books/content/understanding-ranges
> makes a distinction about "range consumption" with regard to a
> "reference type" or a "value type" and it isn't clear to me why
> there would be a difference.
With a value type, you're consuming a copy of the original range,
so you can reuse it after. With a reference type, you're
consuming the original range and therefore can't reuse it.
========
struct ValRange {
int[] items;
bool empty() @property { return items.length == 0; }
int front() @property { return items[0]; }
void popFront() { items = items[1 .. $]; }
}
class RefRange {
int[] items;
this(int[] src) { items = src; }
bool empty() @property { return items.length == 0; }
int front() @property { return items[0]; }
void popFront() { items = items[1 .. $]; }
}
void main() {
import std.stdio;
int[] ints = [1, 2, 3];
auto valRange = ValRange(ints);
writeln("Val 1st Run:");
foreach(i; valRange) writeln(i);
assert(!valRange.empty);
writeln("Val 2nd Run:");
foreach(i; valRange) writeln(i);
assert(!valRange.empty);
auto refRange = new RefRange(ints);
writeln("Ref 1st Run:");
foreach(i; refRange) writeln(i);
assert(refRange.empty);
writeln("Ref 2nd Run:");
foreach(i; refRange) writeln(i); // prints nothing
}
More information about the Digitalmars-d-learn
mailing list