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