Skip to content

Commit 47094dc

Browse files
committed
spec: clarify variable declaration type rules
Not a language change. Several inaccuracies were fixed: 1) A variable declaration may declare more than just one variable. 2) Variable initialization follows the rules of assignments, including n:1 assignments. The existing wording implied a 1:1 or n:n rule and generally was somewhat unspecific. 3) The rules for variable declarations with no types and untyped initialization expressions had minor holes (issue 8088). 4) Clarified the special cases of assignments of untyped values (we don't just have untyped constants, but also untyped bools, e.g. from comparisons). The new wording is more direct. To that end, introduced the notion of an untyped constant's "default type" so that the same concept doesn't have to be repeatedly introduced. Fixes #8088. LGTM=iant, r, rsc R=r, rsc, iant, ken CC=golang-codereviews https://golang.org/cl/142320043
1 parent c017a4e commit 47094dc

File tree

1 file changed

+48
-33
lines changed

1 file changed

+48
-33
lines changed

doc/go_spec.html

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!--{
22
"Title": "The Go Programming Language Specification",
3-
"Subtitle": "Version of September 29, 2014",
3+
"Subtitle": "Version of September 30, 2014",
44
"Path": "/ref/spec"
55
}-->
66

@@ -577,7 +577,7 @@ <h2 id="Constants">Constants</h2>
577577
</p>
578578

579579
<p>
580-
Constants may be <a href="#Types">typed</a> or untyped.
580+
Constants may be <a href="#Types">typed</a> or <i>untyped</i>.
581581
Literal constants, <code>true</code>, <code>false</code>, <code>iota</code>,
582582
and certain <a href="#Constant_expressions">constant expressions</a>
583583
containing only untyped constant operands are untyped.
@@ -597,6 +597,17 @@ <h2 id="Constants">Constants</h2>
597597
not <code>int32</code> or <code>string</code>.
598598
</p>
599599

600+
<p>
601+
An untyped constant has a <i>default type</i> which is the type to which the
602+
constant is implicitly converted in contexts where a typed value is required,
603+
for instance, in a <a href="#Short_variable_declarations">short variable declaration</a>
604+
such as <code>i := 0</code> where there is no explicit type.
605+
The default type of an untyped constant is <code>bool</code>, <code>rune</code>,
606+
<code>int</code>, <code>float64</code>, <code>complex128</code> or <code>string</code>
607+
respectively, depending on whether it is a boolean, rune, integer, floating-point,
608+
complex, or string constant.
609+
</p>
610+
600611
<p>
601612
There are no constants denoting the IEEE-754 infinity and not-a-number values,
602613
but the <a href="/pkg/math/"><code>math</code> package</a>'s
@@ -1882,9 +1893,10 @@ <h3 id="Type_declarations">Type declarations</h3>
18821893
<h3 id="Variable_declarations">Variable declarations</h3>
18831894

18841895
<p>
1885-
A variable declaration creates a variable, binds an identifier to it and
1886-
gives it a type and optionally an initial value.
1896+
A variable declaration creates one or more variables, binds corresponding
1897+
identifiers to them, and gives each a type and an initial value.
18871898
</p>
1899+
18881900
<pre class="ebnf">
18891901
VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
18901902
VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
@@ -1905,22 +1917,27 @@ <h3 id="Variable_declarations">Variable declarations</h3>
19051917

19061918
<p>
19071919
If a list of expressions is given, the variables are initialized
1908-
by <a href="#Assignments">assigning</a> the expressions to the variables
1909-
in order; all expressions must be consumed and all variables initialized from them.
1920+
with the expressions following the rules for <a href="#Assignments">assignments</a>.
19101921
Otherwise, each variable is initialized to its <a href="#The_zero_value">zero value</a>.
19111922
</p>
19121923

19131924
<p>
1914-
If the type is present, each variable is given that type.
1915-
Otherwise, the types are deduced from the assignment
1916-
of the expression list.
1925+
If a type is present, each variable is given that type.
1926+
Otherwise, each variable is given the type of the corresponding
1927+
initialization value in the assignment.
1928+
If that value is an untyped constant, it is first
1929+
<a href="#Conversions">converted</a> to its <a href="#Constants">default type</a>;
1930+
if it is an untyped boolean value, it is first converted to type <code>bool</code>.
1931+
The predeclared value <code>nil</code> cannot be used to initialize a variable
1932+
with no explicit type.
19171933
</p>
19181934

1919-
<p>
1920-
If the type is absent and the corresponding expression evaluates to an
1921-
untyped <a href="#Constants">constant</a>, the type of the declared variable
1922-
is as described in §<a href="#Assignments">Assignments</a>.
1923-
</p>
1935+
<pre>
1936+
var d = math.Sin(0.5) // d is int64
1937+
var i = 42 // i is int
1938+
var t, ok = x.(T) // t is T, ok is bool
1939+
var n = nil // illegal
1940+
</pre>
19241941

19251942
<p>
19261943
Implementation restriction: A compiler may make it illegal to declare a variable
@@ -4318,7 +4335,7 @@ <h3 id="Assignments">Assignments</h3>
43184335

43194336
<p>
43204337
An <i>assignment operation</i> <code>x</code> <i>op</i><code>=</code>
4321-
<code>y</code> where <i>op</i> is a binary arithmetic operation equivalent
4338+
<code>y</code> where <i>op</i> is a binary arithmetic operation is equivalent
43224339
to <code>x</code> <code>=</code> <code>x</code> <i>op</i>
43234340
<code>y</code> but evaluates <code>x</code>
43244341
only once. The <i>op</i><code>=</code> construct is a single token.
@@ -4336,8 +4353,8 @@ <h3 id="Assignments">Assignments</h3>
43364353
A tuple assignment assigns the individual elements of a multi-valued
43374354
operation to a list of variables. There are two forms. In the
43384355
first, the right hand operand is a single multi-valued expression
4339-
such as a function evaluation or <a href="#Channel_types">channel</a> or
4340-
<a href="#Map_types">map</a> operation or a <a href="#Type_assertions">type assertion</a>.
4356+
such as a function call, a <a href="#Channel_types">channel</a> or
4357+
<a href="#Map_types">map</a> operation, or a <a href="#Type_assertions">type assertion</a>.
43414358
The number of operands on the left
43424359
hand side must match the number of values. For instance, if
43434360
<code>f</code> is a function returning two values,
@@ -4411,23 +4428,21 @@ <h3 id="Assignments">Assignments</h3>
44114428
</p>
44124429

44134430
<ol>
4414-
<li><p>
4415-
If an untyped <a href="#Constants">constant</a>
4431+
<li>
4432+
Any typed value may be assigned to the blank identifier.
4433+
</li>
4434+
4435+
<li>
4436+
If an untyped constant
44164437
is assigned to a variable of interface type or the blank identifier,
4417-
the constant is first <a href="#Conversions">converted</a> to type
4418-
<code>bool</code>, <code>rune</code>, <code>int</code>, <code>float64</code>,
4419-
<code>complex128</code> or <code>string</code> respectively, depending on
4420-
whether the value is a boolean, rune, integer, floating-point, complex, or
4421-
string constant.
4422-
</p></li>
4423-
4424-
<li><p>
4425-
<!-- Note that the result of a comparison is an untyped bool that may not be constant. -->
4426-
If a left-hand side is the blank identifier, any typed or non-constant
4427-
value except for the predeclared identifier
4428-
<a href="#Predeclared_identifiers"><code>nil</code></a>
4429-
may be assigned to it.
4430-
</p></li>
4438+
the constant is first <a href="#Conversions">converted</a> to its
4439+
<a href="#Constants">default type</a>.
4440+
</li>
4441+
4442+
<li>
4443+
If an untyped boolean value is assigned to a variable of interface type or
4444+
the blank identifier, it is first converted to type <code>bool</code>.
4445+
</li>
44314446
</ol>
44324447

44334448
<h3 id="If_statements">If statements</h3>

0 commit comments

Comments
 (0)