diff options
author | Robert Griesemer <gri@golang.org> | 2010-09-28 14:44:19 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2010-09-28 14:44:19 -0700 |
commit | 2c6f64b2f9add8ae86d1d57752e0d1a572ff112b (patch) | |
tree | 450634663418b4d0e70f32c4e626ff87dd1e5388 /doc | |
parent | 30dd3e3893a774a35ae5db0974454607cc2d0576 (diff) | |
download | go-2c6f64b2f9add8ae86d1d57752e0d1a572ff112b.tar.gz |
go spec: clarifications for range clause
R=iant, r, rsc, rog
CC=golang-dev
http://codereview.appspot.com/2226047
Diffstat (limited to 'doc')
-rw-r--r-- | doc/go_spec.html | 123 |
1 files changed, 70 insertions, 53 deletions
diff --git a/doc/go_spec.html b/doc/go_spec.html index ea7a75c49..8e1b45ab9 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> |