]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.2] spec: clarify rules for blank identifiers
authorAndrew Gerrand <adg@golang.org>
Wed, 13 Nov 2013 03:40:41 +0000 (14:40 +1100)
committerRuss Cox <rsc@golang.org>
Wed, 13 Nov 2013 03:40:41 +0000 (14:40 +1100)
««« CL 14415043 / 4daa80747394
spec: clarify rules for blank identifiers

This documents the status quo more precisely.
Not a language change.

Fixes #6006.

R=r, rsc, iant, ken
CC=golang-dev
https://golang.org/cl/14415043

»»»

R=golang-dev
CC=golang-dev
https://golang.org/cl/25790043

doc/go_spec.html

index 87ee7459ff73d109eb9bf7380aa02ec0ebc95bf4..bc9ec682a0a501cc49e269d8fdfde8b7efdad541 100644 (file)
@@ -1,6 +1,6 @@
 <!--{
        "Title": "The Go Programming Language Specification",
-       "Subtitle": "Version of Oct 16, 2013",
+       "Subtitle": "Version of Nov 13, 2013",
        "Path": "/ref/spec"
 }-->
 
@@ -1456,10 +1456,6 @@ by a value of type <code>T</code>.
 </li>
 </ul>
 
-<p>
-Any value may be assigned to the <a href="#Blank_identifier">blank identifier</a>.
-</p>
-
 
 <h2 id="Blocks">Blocks</h2>
 
@@ -1516,6 +1512,11 @@ No identifier may be declared twice in the same block, and
 no identifier may be declared in both the file and package block.
 </p>
 
+<p>
+The <a href="#Blank_identifier">blank identifier</a> may be used like any other identifier
+in a declaration, but it does not introduce a binding and thus is not declared.
+</p>
+
 <pre class="ebnf">
 Declaration   = ConstDecl | TypeDecl | VarDecl .
 TopLevelDecl  = Declaration | FunctionDecl | MethodDecl .
@@ -1585,8 +1586,10 @@ the body of any nested function.
 <h3 id="Blank_identifier">Blank identifier</h3>
 
 <p>
-The <i>blank identifier</i>, represented by the underscore character <code>_</code>, may be used in a declaration like
-any other identifier but the declaration does not introduce a new <a href="#Declarations_and_scope">binding</a>.
+The <i>blank identifier</i> is represented by the underscore character <code>_</code>.
+It serves as an anonymous placeholder instead of a regular (non-blank)
+identifier and has special meaning in <a href="#Declarations_and_scope">declarations</a>,
+as an <a href="#Operands">operand</a>, and in <a href="#Assignments">assignments</a>.
 </p>
 
 
@@ -2077,8 +2080,8 @@ operators and functions to operands.
 
 <p>
 Operands denote the elementary values in an expression. An operand may be a
-literal, a (possibly <a href="#Qualified_identifiers">qualified</a>) identifier
-denoting a
+literal, a (possibly <a href="#Qualified_identifiers">qualified</a>)
+non-<a href="#Blank_identifier">blank</a> identifier denoting a
 <a href="#Constant_declarations">constant</a>,
 <a href="#Variable_declarations">variable</a>, or
 <a href="#Function_declarations">function</a>,
@@ -2086,6 +2089,11 @@ a <a href="#Method_expressions">method expression</a> yielding a function,
 or a parenthesized expression.
 </p>
 
+<p>
+The <a href="#Blank_identifier">blank identifier</a> may appear as an
+operand only on the left-hand side of an <a href="#Assignments">assignment</a>.
+</p>
+
 <pre class="ebnf">
 Operand    = Literal | OperandName | MethodExpr | "(" Expression ")" .
 Literal    = BasicLit | CompositeLit | FunctionLit .
@@ -4255,7 +4263,8 @@ assign_op = [ add_op | mul_op ] "=" .
 
 <p>
 Each left-hand side operand must be <a href="#Address_operators">addressable</a>,
-a map index expression, or the <a href="#Blank_identifier">blank identifier</a>.
+a map index expression, or (for <code>=</code> assignments only) the
+<a href="#Blank_identifier">blank identifier</a>.
 Operands may be parenthesized.
 </p>
 
@@ -4268,12 +4277,13 @@ a[i] = 23
 
 <p>
 An <i>assignment operation</i> <code>x</code> <i>op</i><code>=</code>
-<code>y</code> where <i>op</i> is a binary arithmetic operation is equivalent
+<code>y</code> where <i>op</i> is a binary arithmetic operation equivalent
 to <code>x</code> <code>=</code> <code>x</code> <i>op</i>
 <code>y</code> but evaluates <code>x</code>
 only once.  The <i>op</i><code>=</code> construct is a single token.
 In assignment operations, both the left- and right-hand expression lists
-must contain exactly one single-valued expression.
+must contain exactly one single-valued expression, and the left-hand
+expression must not be the blank identifier.
 </p>
 
 <pre>
@@ -4298,21 +4308,26 @@ x, y = f()
 
 <p>
 assigns the first value to <code>x</code> and the second to <code>y</code>.
-The <a href="#Blank_identifier">blank identifier</a> provides a
-way to ignore values returned by a multi-valued expression:
+In the second form, the number of operands on the left must equal the number
+of expressions on the right, each of which must be single-valued, and the
+<i>n</i>th expression on the right is assigned to the <i>n</i>th
+operand on the left:
 </p>
 
 <pre>
-x, _ = f()  // ignore second value returned by f()
+one, two, three = '一', '二', '三'
 </pre>
 
 <p>
-In the second form, the number of operands on the left must equal the number
-of expressions on the right, each of which must be single-valued, and the
-<i>n</i>th expression on the right is assigned to the <i>n</i>th
-operand on the left.
+The <a href="#Blank_identifier">blank identifier</a> provides a way to
+ignore right-hand side values in an assignment:
 </p>
 
+<pre>
+_ = x       // evaluate x but ignore it
+x, _ = f()  // evaluate f() but ignore second result value
+</pre>
+
 <p>
 The assignment proceeds in two phases.
 First, the operands of <a href="#Index_expressions">index expressions</a>
@@ -4350,16 +4365,29 @@ for i, x[i] = range x {  // set i, x[2] = 0, x[0]
 </pre>
 
 <p>
-In assignments, each value must be
-<a href="#Assignability">assignable</a> to the type of the
-operand to which it is assigned. If an untyped <a href="#Constants">constant</a>
-is assigned to a variable of interface type, the constant is <a href="#Conversions">converted</a>
-to type <code>bool</code>, <code>rune</code>, <code>int</code>, <code>float64</code>,
-<code>complex128</code> or <code>string</code>
-respectively, depending on whether the value is a
-boolean, rune, integer, floating-point, complex, or string constant.
+In assignments, each value must be <a href="#Assignability">assignable</a>
+to the type of the operand to which it is assigned, with the following special cases:
 </p>
 
+<ol>
+<li><p>
+       If an untyped <a href="#Constants">constant</a>
+       is assigned to a variable of interface type or the blank identifier,
+       the constant is first <a href="#Conversions">converted</a> to type
+       <code>bool</code>, <code>rune</code>, <code>int</code>, <code>float64</code>,
+       <code>complex128</code> or <code>string</code> respectively, depending on
+       whether the value is a boolean, rune, integer, floating-point, complex, or
+       string constant.
+</p></li>
+
+<li><p>
+       <!-- Note that the result of a comparison is an untyped bool that may not be constant. -->
+       If a left-hand side is the blank identifier, any typed or non-constant
+       value except for the predeclared identifier
+       <a href="#Predeclared_identifiers"><code>nil</code></a>
+       may be assigned to it.
+</p></li>
+</ol>
 
 <h3 id="If_statements">If statements</h3>