From 20ae6d9bc58f98355fcab6501e0fcb2c5b34f44c Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Mon, 14 Jul 2014 15:08:09 -0700 Subject: [PATCH] spec: permit "for range x" (no index variables) This is a fully backward-compatible language change. There are not a lot of cases in the std library, but there are some. Arguably this makes the syntax a bit more regular - any trailing index variable that is _ can be left away, and there's some analogy to type switches where the temporary can be left away. Implementation-wise the change should be trivial as it can be done completely syntactically. For instance, the respective change in go/parser is a dozen lines (see https://golang.org/cl/112970044 ). Fixes #6102. LGTM=iant, r, rsc R=r, rsc, iant, ken CC=golang-codereviews https://golang.org/cl/104680043 --- doc/go_spec.html | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index ca9e50203e..8832375378 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -4714,41 +4714,42 @@ for { S() } is the same as for true { S() } A "for" statement with a "range" clause iterates through all entries of an array, slice, string or map, or values received on a channel. For each entry it assigns iteration values -to corresponding iteration variables and then executes the block. +to corresponding iteration variables if present and then executes the block.

-RangeClause = ( ExpressionList "=" | IdentifierList ":=" ) "range" Expression .
+RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
 

The expression on the right in the "range" clause is called the range expression, which may be an array, pointer to an array, slice, string, map, or channel permitting receive operations. -As with an assignment, the operands on the left must be +As with an assignment, if present the operands on the left must be addressable or map index expressions; they -denote the iteration variables. If the range expression is a channel, only -one iteration variable is permitted, otherwise there may be one or two. In the latter case, -if the second iteration variable is the blank identifier, -the range clause is equivalent to the same clause with only the first variable present. +denote the iteration variables. If the range expression is a channel, at most +one iteration variable is permitted, otherwise there may be up to two. +If the last iteration variable is the blank identifier, +the range clause is equivalent to the same clause without that identifier.

The range expression is evaluated once before beginning the loop, -with one exception. If the range expression is an array or a pointer to an array -and only the first iteration value is present, only the range expression's -length is evaluated; if that length is constant -by definition, +with one exception: if the range expression is an array or a pointer to an array +and at most one iteration variable is present, only the range expression's +length is evaluated; if that length is constant, +by definition the range expression itself will not be evaluated.

Function calls on the left are evaluated once per iteration. -For each iteration, iteration values are produced as follows: +For each iteration, iteration values are produced as follows +if the respective iteration variables are present:

-Range expression                          1st value          2nd value (if 2nd variable is present)
+Range expression                          1st value          2nd value
 
 array or slice  a  [n]E, *[n]E, or []E    index    i  int    a[i]       E
 string          s  string type            index    i  int    see below  rune
@@ -4760,7 +4761,7 @@ channel         c  chan E, <-chan E       element  e  E
 
  • For an array, pointer to array, or slice value a, the index iteration values are produced in increasing order, starting at element index 0. -If only the first iteration variable is present, the range loop produces +If at most one iteration variable is present, the range loop produces iteration values from 0 up to len(a)-1 and does not index into the array or slice itself. For a nil slice, the number of iterations is 0.
  • @@ -4841,6 +4842,9 @@ var ch chan Work = producer() for w := range ch { doWork(w) } + +// empty a channel +for range ch {}
    -- 2.48.1