Skip to content

Commit b90c1f3

Browse files
authored
Merge pull request #3203 from ntrel/foreach
[spec/statement.dd] Improve foreach docs Signed-off-by: Dennis <dkorpel@users.noreply.github.com> Merged-on-behalf-of: Dennis <dkorpel@users.noreply.github.com>
2 parents 7d731a1 + bf2ad3e commit b90c1f3

File tree

1 file changed

+40
-35
lines changed

1 file changed

+40
-35
lines changed

spec/statement.dd

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ for (int i = 0; i < 10; i++)
444444

445445
$(H2 $(LEGACY_LNAME2 ForeachStatement, foreach-statement, Foreach Statement))
446446

447-
$(P A `foreach` statement loops over the contents of an aggregate.)
447+
$(P A `foreach` statement iterates a series of values.)
448448

449449
$(GRAMMAR
450450
$(GNAME AggregateForeach):
@@ -482,17 +482,39 @@ $(GNAME ForeachAggregate):
482482

483483
$(P
484484
$(I ForeachAggregate) is evaluated. It must evaluate to an expression
485-
of type static array, dynamic array, associative array,
485+
which is a static array, dynamic array, associative array,
486486
struct, class, delegate, or sequence.
487487
The *NoScopeNonEmptyStatement* is executed, once for each element of the
488488
aggregate.
489-
At the start of each iteration, the variables declared by
490-
the $(I ForeachTypeList)
491-
are set to be a copy of the elements of the aggregate.
492-
If the $(I ForeachTypeAttribute) is $(D ref), it is a reference to the
493-
contents of that aggregate.
494-
If the $(I ForeachTypeAttribute) is $(D scope), the $(I ForeachType) declaration
495-
will have $(D scope) semantics.
489+
)
490+
$(P
491+
The number of variables declared in $(I ForeachTypeList)
492+
depends on the kind of aggregate. The declared variables are
493+
set at the start of each iteration.
494+
)
495+
$(UL
496+
$(LI By default a single declared variable is a copy of the current element.)
497+
$(LI If the $(I ForeachTypeAttribute) is $(D ref), that variable will
498+
be a reference to the current element of the aggregate.)
499+
$(LI If the $(I ForeachTypeAttribute) is $(D scope), the variable
500+
will have $(DDSUBLINK spec/function, scope-parameters, `scope`) semantics.)
501+
)
502+
$(P
503+
If not specified, the type of a $(I ForeachType) variable
504+
can be inferred from the type of the $(I ForeachAggregate).
505+
Note that `auto` is not a valid $(I ForeachTypeAttribute).
506+
The two `foreach` statements below are equivalent:
507+
)
508+
$(SPEC_RUNNABLE_EXAMPLE_RUN
509+
--------------
510+
int[] arr = [1, 2, 3];
511+
512+
foreach (int n; arr)
513+
writeln(n);
514+
515+
foreach (n; arr) // ok, n is an int
516+
writeln(n);
517+
--------------
496518
)
497519
$(P
498520
The aggregate must be loop invariant, meaning that
@@ -501,7 +523,7 @@ $(P
501523
)
502524

503525
$(P A $(GLINK BreakStatement) in the body of the foreach will exit the
504-
foreach, a $(GLINK ContinueStatement) will immediately start the
526+
loop. A $(GLINK ContinueStatement) will immediately start the
505527
next iteration.
506528
)
507529

@@ -540,21 +562,6 @@ foreach (size_t i, char c; a)
540562
order.
541563
)
542564

543-
$(P $(B Note:) The $(I ForeachTypeAttribute) is implicit, and when a
544-
type is not specified, it is inferred. In that case, $(D auto) is
545-
implied, and it is not necessary (and actually forbidden) to use it.
546-
)
547-
548-
--------------
549-
int[] arr;
550-
...
551-
foreach (n; arr) // ok, n is an int
552-
writeln(n);
553-
554-
foreach (auto n; arr) // error, auto is redundant
555-
writeln(n);
556-
--------------
557-
558565
$(H3 $(LNAME2 foreach_over_arrays_of_characters, Foreach over Arrays of Characters))
559566

560567
$(P If the aggregate expression is a static or dynamic array of
@@ -1005,7 +1012,8 @@ main()
10051012

10061013
$(H3 $(LNAME2 foreach_ref_parameters, Foreach Ref Parameters))
10071014

1008-
$(P $(D ref) can be used to update the original elements:
1015+
$(P $(D ref) can be used to update the original elements for some
1016+
kinds of container. Arrays support this:
10091017
)
10101018

10111019
$(SPEC_RUNNABLE_EXAMPLE_RUN
@@ -1029,12 +1037,7 @@ $(CONSOLE
10291037
8
10301038
9
10311039
)
1032-
$(P $(D ref) can not be applied to the index values.)
1033-
1034-
$(P If not specified, the $(I Type)s in the $(I ForeachType) can be
1035-
inferred from
1036-
the type of the $(I ForeachAggregate).
1037-
)
1040+
$(P $(D ref) cannot be applied to an array index variable.)
10381041

10391042
$(H3 $(LNAME2 foreach_restrictions, Foreach Restrictions))
10401043

@@ -1075,11 +1078,13 @@ $(GNAME ForeachRangeStatement):
10751078

10761079
$(P
10771080
$(I ForeachType) declares a variable with either an explicit type,
1078-
or a type inferred from $(I LwrExpression) and $(I UprExpression).
1081+
or a common type inferred from $(I LwrExpression) and $(I UprExpression).
10791082
The $(I ScopeStatement) is then executed $(I n) times, where $(I n)
1080-
is the result of $(I UprExpression) - $(I LwrExpression).
1083+
is the result of $(I UprExpression) `-` $(I LwrExpression).
10811084
If $(I UprExpression) is less than or equal to $(I LwrExpression),
1082-
the $(I ScopeStatement) is executed zero times.
1085+
the $(I ScopeStatement) is not executed.)
1086+
1087+
$(P
10831088
If $(I Foreach) is $(D foreach), then the variable is set to
10841089
$(I LwrExpression), then incremented at the end of each iteration.
10851090
If $(I Foreach) is $(D foreach_reverse), then the variable is set to

0 commit comments

Comments
 (0)