Search code examples
d

for and foreach statements in D


Besides the syntactic differences, are the two inherently the same? Are both of them implemented in the core language? or is foreach part of the standard library? And as far as performance, does it make a difference if I choose one over the other?


Solution

  • You should always use foreach if possible.

    1. foreach iterate over practically anything (even metadata, like compile-time data types); for can't.

      foreach (Type; TypeTuple!(int, long, short)) { pragma(msg, Type); }
      

      but you can't do that with a for loop.

    2. foreach can be used to perform actions at compile-time (extension of above); for example, if you have a piece of code that repeats 10 times, you can say:

      template Iota(size_t a, size_t b) //All integers in the range [a, b)
      {
          static if (a < b) { alias TypeTuple!(a, Iota!(a + 1, b)) Iota; }
          else { alias TypeTuple!() Iota; }
      }
      
      foreach (i; Iota!(0, 10)) { int[i] arr; } //Not possible with 'for'
      

      and this will occur at compile-time, with i treated as a constant. (This doesn't normally work with for.)

    3. foreach can be overloaded with opApply and also with range constructs, but for can't. This is very handy when iterating a tree structure (like all the folders in a file system), because it actually allows you to use entirely stack-based memory rather than allocating on the heap (because you can use recursion).

    4. foreach is preferred in most situations because it prevents the need for you to type your data explicitly, which is useful in preventing some bugs. For example,

      for (int i = 0; i < n; i++) { arr[i]++; }
      

      is dangerous if n is greater than 2^32 - 1, but

      foreach (i; 0 .. n) { arr[i]++; }
      

      is not, because the compiler automatically chooses the correct type for iteration. This also improves readability.