aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2010-09-28 14:44:19 -0700
committerRobert Griesemer <gri@golang.org>2010-09-28 14:44:19 -0700
commit5474e166bc0b6c69a0a44730c19ecba09b1f9ed2 (patch)
tree400d4adc1ce798c85d696683acb4a477a5446873
parent2ccbf83b327a214a5b8d7e5f03c2d248e6d473e5 (diff)
downloadgo-5474e166bc0b6c69a0a44730c19ecba09b1f9ed2.tar.gz
go-5474e166bc0b6c69a0a44730c19ecba09b1f9ed2.zip
go spec: clarifications for range clause
R=iant, r, rsc, rog CC=golang-dev https://golang.org/cl/2226047
-rw-r--r--doc/go_spec.html123
1 files changed, 70 insertions, 53 deletions
diff --git a/doc/go_spec.html b/doc/go_spec.html
index ea7a75c497..8e1b45ab96 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,5 +1,5 @@
<!-- title The Go Programming Language Specification -->
-<!-- subtitle Version of Sep 27, 2010 -->
+<!-- subtitle Version of Sep 28, 2010 -->
<!--
TODO
@@ -14,7 +14,6 @@ TODO
[ ] should string(1<<s) and float(1<<s) be valid?
[ ] should probably write something about evaluation order of statements even
though obvious
-[ ] specify iteration direction for range clause
[ ] review language on implicit dereferencing
[ ] clarify what it means for two functions to be "the same" when comparing them
-->
@@ -3572,8 +3571,8 @@ f(x+y)
<p>
The "++" and "--" statements increment or decrement their operands
by the untyped <a href="#Constants">constant</a> <code>1</code>.
-As with an assignment, the operand must be a variable, pointer indirection,
-field selector or index expression.
+As with an assignment, the operand must be <a href="#Address_operators">addressable</a>
+or a map index expression.
</p>
<pre class="ebnf">
@@ -3591,6 +3590,7 @@ x++ x += 1
x-- x -= 1
</pre>
+
<h3 id="Assignments">Assignments</h3>
<pre class="ebnf">
@@ -3949,59 +3949,81 @@ for { S() } is the same as for true { S() }
<p>
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 first assigns the current index or key to an iteration
-variable - or the current (index, element) or (key, value) pair to a pair
-of iteration variables - and then executes the block.
+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.
</p>
<pre class="ebnf">
-RangeClause = ExpressionList ( "=" | ":=" ) "range" Expression .
-</pre>
-
-<p>
-The type of the right-hand expression in the "range" clause must be an
-array, slice, string or map, or a pointer to an array;
-or it may be a channel.
-Except for channels,
-the identifier list must contain one or two expressions
-(as in assignments, these must be a
-variable, pointer indirection, field selector, or index expression)
-denoting the
-iteration variables. On each iteration,
-the first variable is set to the string, array or slice index or
-map key, and the second variable, if present, is set to the corresponding
-string or array element or map value.
-The types of the array or slice index (always <code>int</code>)
-and element, or of the map key and value respectively,
-must be <a href="#Assignability">assignable</a> to
-the type of the iteration variables. The expression on the right hand
-side is evaluated once before beginning the loop. At each iteration
-of the loop, the values produced by the range clause are assigned to
-the left hand side as in an <a href="#Assignments">assignment
-statement</a>. Function calls on the left hand side will be evaluated
-exactly once per iteration.
-</p>
-<p>
-For a value of a string type, the "range" clause iterates over the Unicode code points
-in the string. On successive iterations, the index variable will be the
-index of the first byte of successive UTF-8-encoded code points in the string, and
-the second variable, of type <code>int</code>, will be the value of
+RangeClause = Expression [ "," Expression ] ( "=" | ":=" ) "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.
+As with an assignment, 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.
+<p>
+
+</p>
+The range expression is evaluated once before beginning the loop.
+Function calls on the left are evaluated once per iteration.
+For each iteration, iteration values are produced as follows:
+</p>
+
+<pre class="grammar">
+Range expression 1st value 2nd value (if 2nd variable is present)
+
+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 int
+map m map[K]V key k K m[k] V
+channel c chan E element e E
+</pre>
+
+<ol>
+<li>
+For an array or slice value, the index iteration values are produced in
+increasing order, starting at element index 0.
+</li>
+
+<li>
+For a string value, the "range" clause iterates over the Unicode code points
+in the string starting at byte index 0. On successive iterations, the index value will be the
+index of the first byte of successive UTF-8-encoded code points in the string,
+and the second value, of type <code>int</code>, will be the value of
the corresponding code point. If the iteration encounters an invalid
-UTF-8 sequence, the second variable will be <code>0xFFFD</code>,
+UTF-8 sequence, the second value will be <code>0xFFFD</code>,
the Unicode replacement character, and the next iteration will advance
a single byte in the string.
-</p>
+</li>
+
+<li>
+The iteration order over maps is not specified.
+If map entries that have not yet been reached are deleted during iteration,
+the corresponding iteration values will not be produced. If map entries are
+inserted during iteration, the behavior is implementation-dependent, but the
+iteration values for each entry will be produced at most once.
+</li>
+
+<li>
+For channels, the iteration values produced are the successive values sent on
+the channel until the channel is closed; it does not produce the zero value sent
+before the channel is closed
+(§<a href="#Close_and_closed"><code>close</code> and <code>closed</code></a>).
+</li>
+</ol
+
<p>
-For channels, the identifier list must contain one identifier.
-The iteration receives values sent on the channel until the channel is closed;
-it does not process the zero value sent before the channel is closed.
+The iteration values are assigned to the respective
+iteration variables as in an <a href="#Assignments">assignment statement</a>.
</p>
+
<p>
-The iteration variables may be declared by the "range" clause (":="), in which
-case their scope ends at the end of the "for" statement (§<a href="#Declarations_and">Declarations and</a>
-scope rules). In this case their types are set to
-<code>int</code> and the array element type, or the map key and value types, respectively.
+The iteration variables may be declared by the "range" clause (<code>:=</code>).
+In this case their types are set to the types of the respective iteration values
+and their <a href="#Declarations_and_scope">scope</a> ends at the end of the "for"
+statement; they are re-used in each iteration.
If the iteration variables are declared outside the "for" statement,
after execution their values will be those of the last iteration.
</p>
@@ -4026,11 +4048,6 @@ for key, val = range m {
// val == map[key]
</pre>
-<p>
-If map entries that have not yet been processed are deleted during iteration,
-they will not be processed. If map entries are inserted during iteration, the
-behavior is implementation-dependent, but each entry will be processed at most once.
-</p>
<h3 id="Go_statements">Go statements</h3>