User defined type and foreach

Tony tonytdominguez at aol.com
Fri Nov 17 17:37:01 UTC 2017


On Friday, 17 November 2017 at 07:40:35 UTC, Mike Parker wrote:

>
> 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
> }

Thanks for the reference and the code. I will have to iterate 
over the packpub text a while consulting the docs. I see that the 
code runs as you say, but I don't understand what's going on. You 
say with regard to a "value type" : "you're consuming a copy of 
the original range" but I don't see anything different between 
the processing in the struct versus in the class. They both have 
a dynamic array variable that they re-assign a "slice" to (or 
maybe that is - that they modify to be the sliced version). 
Anyway, I can't see why the one in the struct shrinks and then 
goes back to what it was originally. It's like calls were made by 
the compiler that aren't shown.



More information about the Digitalmars-d-learn mailing list