diff options
author | Robert Griesemer <gri@golang.org> | 2014-07-14 15:08:09 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2014-07-14 15:08:09 -0700 |
commit | 540b2fc66720a82374f09589ecd2f6b550db38dc (patch) | |
tree | 6d47fc9d7b8337c772713ab691edb2180915d38f /doc/go_spec.html | |
parent | 65e3260909e3d2ca33e4f3ee43322febfe25325f (diff) | |
download | go-540b2fc66720a82374f09589ecd2f6b550db38dc.tar.gz |
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://codereview.appspot.com/112970044 ).
Fixes issue 6102.
LGTM=iant, r, rsc
R=r, rsc, iant, ken
CC=golang-codereviews
https://codereview.appspot.com/104680043
Diffstat (limited to 'doc/go_spec.html')
-rw-r--r-- | doc/go_spec.html | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/doc/go_spec.html b/doc/go_spec.html index ca9e50203..883237537 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ <!--{ "Title": "The Go Programming Language Specification", - "Subtitle": "Version of June 24, 2014", + "Subtitle": "Version of July 14, 2014", "Path": "/ref/spec" }--> @@ -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 <i>iteration values</i> -to corresponding <i>iteration variables</i> and then executes the block. +to corresponding <i>iteration variables</i> if present and then executes the block. </p> <pre class="ebnf"> -RangeClause = ( ExpressionList "=" | IdentifierList ":=" ) "range" Expression . +RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression . </pre> <p> The expression on the right in the "range" clause is called the <i>range expression</i>, which may be an array, pointer to an array, slice, string, map, or channel permitting <a href="#Receive_operator">receive operations</a>. -As with an assignment, the operands on the left must be +As with an assignment, if present the operands on the left must be <a href="#Address_operators">addressable</a> 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 <a href="#Blank_identifier">blank identifier</a>, -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 <a href="#Blank_identifier">blank identifier</a>, +the range clause is equivalent to the same clause without that identifier. </p> <p> 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 -<a href="#Length_and_capacity">by definition</a>, +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, +<a href="#Length_and_capacity">by definition</a> the range expression itself will not be evaluated. </p> <p> 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: </p> <pre class="grammar"> -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 <li> For an array, pointer to array, or slice value <code>a</code>, 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 <code>len(a)-1</code> and does not index into the array or slice itself. For a <code>nil</code> slice, the number of iterations is 0. </li> @@ -4841,6 +4842,9 @@ var ch chan Work = producer() for w := range ch { doWork(w) } + +// empty a channel +for range ch {} </pre> |