Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
a local clone.
static_foreach
We saw compile-time foreach earlier in the Tuples chapter. Compile-time foreach iterates the loop at compile time and unrolls each iteration as separate pieces of code. For example, given the following foreach loop over a tuple:
auto t = tuple(42, "hello", 1.5); foreach (i, member; t) { writefln("%s: %s", i, member); }
The compiler unrolls the loop similar to the following equivalent code:
{
enum size_t i = 0;
int member = t[i];
writefln("%s: %s", i, member);
}
{
enum size_t i = 1;
string member = t[i];
writefln("%s: %s", i, member);
}
{
enum size_t i = 2;
double member = t[i];
writefln("%s: %s", i, member);
}
Although being very powerful, some properties of compile-time foreach may not be suitable in some cases:
- With compile-time
foreach, each unrolling of the loop introduces a scope. As seen with theiandmembervariables above, this allows the use of a symbol in more than one scope without causing a multiple definition error. Although this can be desirable in some cases, it makes it impossible for code unrolled for one iteration to use code from other iterations. - Compile-time
foreachworks only with tuples (including template arguments in the form ofAliasSeq). For example, despite the elements of the following array literal being known at compile time, the loop will always be executed at run time (this may very well be the desired behavior):
void main() { enum arr = [1, 2]; // Executed at run time, not unrolled at compile time: foreach (i; arr) { // ... } }
- Like regular
foreach, compile-timeforeachcan only be used inside functions. For example, it cannot be used at module scope or inside a user-defined type definition.
import std.meta; // Attempting to define function overloads at module scope: foreach (T; AliasSeq!(int, double)) { // ← derleme HATASI T twoTimes(T arg) { return arg * 2; } } void main() { }
Error: declaration expected, not foreach
- With compile-time
foreach, it may not be clear whetherbreakandcontinuestatements inside the loop body should affect the compile-time loop iteration itself or whether they should be parts of the unrolled code.
static foreach is a more powerful compile-time feature that provides more control:
static foreachcan work with any range of elements that can be computed at compile time (including number ranges like1..10). For example, given theFibonacciSeriesrange from the Ranges chapter and a function that determines whether a number is even:
static foreach (n; FibonacciSeries().take(10).filter!isEven) {
writeln(n);
}
The loop above would be unrolled as the following equivalent:
writeln(0);
writeln(2);
writeln(8);
writeln(34);
static foreachcan be used at module scope.static foreachdoes not introduce a separate scope for each iteration. For example, the following loop defines two overloads of a function at module scope:
import std.meta; static foreach (T; AliasSeq!(int, double)) { T twoTimes(T arg) { return arg * 2; } } void main() { }
The loop above would be unrolled as its following equivalent:
int twoTimes(int arg) { return arg * 2; } double twoTimes(double arg) { return arg * 2; }
breakandcontinuestatements inside astatic foreachloop require labels for clarity. For example, the following code unrolls (generates)caseclauses inside aswitchstatement. Thebreakstatements that are under eachcaseclause must mention the associatedswitchstatements by labels:
import std.stdio; void main(string[] args) { theSwitchStatement: switch (args.length) { static foreach (i; 1..3) { case i: writeln(i); break theSwitchStatement; } default: writeln("default case"); break; } }
After the loop above is unrolled, the switch statement would be the equivalent of the following code:
switch (args.length) { case 1: writeln(1); break; case 2: writeln(2); break; default: writeln("default case"); break; }macros: TITLE=static foreach DESCRIPTION=static foreach, one of D's compile-time feature that can generate code by iterating ranges. KEYWORDS=d programming language tutorial book static foreach MINI_SOZLUK=
Copyright © 1999-2025 by the D Language Foundation | Page generated by
Ddoc on Fri Oct 10 22:17:27 2025