From f484994d7ada7e0988b1e125b12b0d91a1a31d43 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 30 Sep 2014 11:44:29 -0700 Subject: 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 issue 8088. LGTM=iant, r, rsc R=r, rsc, iant, ken CC=golang-codereviews https://codereview.appspot.com/142320043 --- doc/go_spec.html | 81 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 33 deletions(-) (limited to 'doc') diff --git a/doc/go_spec.html b/doc/go_spec.html index de79f7ee4..7fa02e419 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -577,7 +577,7 @@ Numeric constants represent values of arbitrary precision and do not overflow.

-Constants may be typed or untyped. +Constants may be typed or untyped. Literal constants, true, false, iota, and certain constant expressions containing only untyped constant operands are untyped. @@ -597,6 +597,17 @@ can be given the types float32, float64, or uint not int32 or string.

+

+An untyped constant has a default type which is the type to which the +constant is implicitly converted in contexts where a typed value is required, +for instance, in a short variable declaration +such as i := 0 where there is no explicit type. +The default type of an untyped constant is bool, rune, +int, float64, complex128 or string +respectively, depending on whether it is a boolean, rune, integer, floating-point, +complex, or string constant. +

+

There are no constants denoting the IEEE-754 infinity and not-a-number values, but the math package's @@ -1882,9 +1893,10 @@ func (tz TimeZone) String() string {

Variable declarations

-A variable declaration creates a variable, binds an identifier to it and -gives it a type and optionally an initial value. +A variable declaration creates one or more variables, binds corresponding +identifiers to them, and gives each a type and an initial value.

+
 VarDecl     = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
 VarSpec     = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
@@ -1905,22 +1917,27 @@ var _, found = entries[name]  // map lookup; only interested in "found"
 
 

If a list of expressions is given, the variables are initialized -by assigning the expressions to the variables -in order; all expressions must be consumed and all variables initialized from them. +with the expressions following the rules for assignments. Otherwise, each variable is initialized to its zero value.

-If the type is present, each variable is given that type. -Otherwise, the types are deduced from the assignment -of the expression list. +If a type is present, each variable is given that type. +Otherwise, each variable is given the type of the corresponding +initialization value in the assignment. +If that value is an untyped constant, it is first +converted to its default type; +if it is an untyped boolean value, it is first converted to type bool. +The predeclared value nil cannot be used to initialize a variable +with no explicit type.

-

-If the type is absent and the corresponding expression evaluates to an -untyped constant, the type of the declared variable -is as described in ยงAssignments. -

+
+var d = math.Sin(0.5)  // d is int64
+var i = 42             // i is int
+var t, ok = x.(T)      // t is T, ok is bool
+var n = nil            // illegal
+

Implementation restriction: A compiler may make it illegal to declare a variable @@ -4318,7 +4335,7 @@ a[i] = 23

An assignment operation x op= -y where op is a binary arithmetic operation equivalent +y where op is a binary arithmetic operation is equivalent to x = x op y but evaluates x only once. The op= construct is a single token. @@ -4336,8 +4353,8 @@ i &^= 1<<n A tuple assignment assigns the individual elements of a multi-valued operation to a list of variables. There are two forms. In the first, the right hand operand is a single multi-valued expression -such as a function evaluation or channel or -map operation or a type assertion. +such as a function call, a channel or +map operation, or a type assertion. The number of operands on the left hand side must match the number of values. For instance, if f is a function returning two values, @@ -4411,23 +4428,21 @@ to the type of the operand to which it is assigned, with the following special c

    -
  1. - If an untyped constant +

  2. + Any typed value may be assigned to the blank identifier. +
  3. + +
  4. + If an untyped constant is assigned to a variable of interface type or the blank identifier, - the constant is first converted to type - bool, rune, int, float64, - complex128 or string respectively, depending on - whether the value is a boolean, rune, integer, floating-point, complex, or - string constant. -

  5. - -
  6. - - If a left-hand side is the blank identifier, any typed or non-constant - value except for the predeclared identifier - nil - may be assigned to it. -

  7. + the constant is first converted to its + default type. + + +
  8. + If an untyped boolean value is assigned to a variable of interface type or + the blank identifier, it is first converted to type bool. +

If statements

-- cgit v1.2.1