mirror of
https://github.com/golang/go
synced 2024-11-13 15:00:23 -07:00
go spec: clarifications for range clause
R=iant, r, rsc, rog CC=golang-dev https://golang.org/cl/2226047
This commit is contained in:
parent
2ccbf83b32
commit
5474e166bc
115
doc/go_spec.html
115
doc/go_spec.html
@ -1,5 +1,5 @@
|
|||||||
<!-- title The Go Programming Language Specification -->
|
<!-- title The Go Programming Language Specification -->
|
||||||
<!-- subtitle Version of Sep 27, 2010 -->
|
<!-- subtitle Version of Sep 28, 2010 -->
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
TODO
|
TODO
|
||||||
@ -14,7 +14,6 @@ TODO
|
|||||||
[ ] should string(1<<s) and float(1<<s) be valid?
|
[ ] should string(1<<s) and float(1<<s) be valid?
|
||||||
[ ] should probably write something about evaluation order of statements even
|
[ ] should probably write something about evaluation order of statements even
|
||||||
though obvious
|
though obvious
|
||||||
[ ] specify iteration direction for range clause
|
|
||||||
[ ] review language on implicit dereferencing
|
[ ] review language on implicit dereferencing
|
||||||
[ ] clarify what it means for two functions to be "the same" when comparing them
|
[ ] clarify what it means for two functions to be "the same" when comparing them
|
||||||
-->
|
-->
|
||||||
@ -3572,8 +3571,8 @@ f(x+y)
|
|||||||
<p>
|
<p>
|
||||||
The "++" and "--" statements increment or decrement their operands
|
The "++" and "--" statements increment or decrement their operands
|
||||||
by the untyped <a href="#Constants">constant</a> <code>1</code>.
|
by the untyped <a href="#Constants">constant</a> <code>1</code>.
|
||||||
As with an assignment, the operand must be a variable, pointer indirection,
|
As with an assignment, the operand must be <a href="#Address_operators">addressable</a>
|
||||||
field selector or index expression.
|
or a map index expression.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre class="ebnf">
|
<pre class="ebnf">
|
||||||
@ -3591,6 +3590,7 @@ x++ x += 1
|
|||||||
x-- x -= 1
|
x-- x -= 1
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
<h3 id="Assignments">Assignments</h3>
|
<h3 id="Assignments">Assignments</h3>
|
||||||
|
|
||||||
<pre class="ebnf">
|
<pre class="ebnf">
|
||||||
@ -3949,59 +3949,81 @@ for { S() } is the same as for true { S() }
|
|||||||
<p>
|
<p>
|
||||||
A "for" statement with a "range" clause
|
A "for" statement with a "range" clause
|
||||||
iterates through all entries of an array, slice, string or map,
|
iterates through all entries of an array, slice, string or map,
|
||||||
or values received on a channel.
|
or values received on a channel. For each entry it assigns <i>iteration values</i>
|
||||||
For each entry it first assigns the current index or key to an iteration
|
to corresponding <i>iteration variables</i> and then executes the block.
|
||||||
variable - or the current (index, element) or (key, value) pair to a pair
|
|
||||||
of iteration variables - and then executes the block.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre class="ebnf">
|
<pre class="ebnf">
|
||||||
RangeClause = ExpressionList ( "=" | ":=" ) "range" Expression .
|
RangeClause = Expression [ "," Expression ] ( "=" | ":=" ) "range" Expression .
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The type of the right-hand expression in the "range" clause must be an
|
The expression on the right in the "range" clause is called the <i>range expression</i>,
|
||||||
array, slice, string or map, or a pointer to an array;
|
which may be an array, pointer to an array, slice, string, map, or channel.
|
||||||
or it may be a channel.
|
As with an assignment, the operands on the left must be
|
||||||
Except for channels,
|
<a href="#Address_operators">addressable</a> or map index expressions; they
|
||||||
the identifier list must contain one or two expressions
|
denote the iteration variables. If the range expression is a channel, only
|
||||||
(as in assignments, these must be a
|
one iteration variable is permitted, otherwise there may be one or two.
|
||||||
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>
|
<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
|
</p>
|
||||||
index of the first byte of successive UTF-8-encoded code points in the string, and
|
The range expression is evaluated once before beginning the loop.
|
||||||
the second variable, of type <code>int</code>, will be the value of
|
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
|
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
|
the Unicode replacement character, and the next iteration will advance
|
||||||
a single byte in the string.
|
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>
|
<p>
|
||||||
For channels, the identifier list must contain one identifier.
|
The iteration values are assigned to the respective
|
||||||
The iteration receives values sent on the channel until the channel is closed;
|
iteration variables as in an <a href="#Assignments">assignment statement</a>.
|
||||||
it does not process the zero value sent before the channel is closed.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The iteration variables may be declared by the "range" clause (":="), in which
|
The iteration variables may be declared by the "range" clause (<code>:=</code>).
|
||||||
case their scope ends at the end of the "for" statement (§<a href="#Declarations_and">Declarations and</a>
|
In this case their types are set to the types of the respective iteration values
|
||||||
scope rules). In this case their types are set to
|
and their <a href="#Declarations_and_scope">scope</a> ends at the end of the "for"
|
||||||
<code>int</code> and the array element type, or the map key and value types, respectively.
|
statement; they are re-used in each iteration.
|
||||||
If the iteration variables are declared outside the "for" statement,
|
If the iteration variables are declared outside the "for" statement,
|
||||||
after execution their values will be those of the last iteration.
|
after execution their values will be those of the last iteration.
|
||||||
</p>
|
</p>
|
||||||
@ -4026,11 +4048,6 @@ for key, val = range m {
|
|||||||
// val == map[key]
|
// val == map[key]
|
||||||
</pre>
|
</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>
|
<h3 id="Go_statements">Go statements</h3>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user