From d39f5aa373a4422f7a5f3ee764fb0f6b0b719d61 Mon Sep 17 00:00:00 2001
From: Ondřej Surý Composite literals
@@ -2096,7 +2102,7 @@ element index plus one. A slice literal has the form
-[]T{x1, x2, ... xn} +[]T{x1, x2, … xn}
@@ -2104,7 +2110,7 @@ and is a shortcut for a slice operation applied to an array literal:
-[n]T{x1, x2, ... xn}[0 : n] +[n]T{x1, x2, … xn}[0 : n]
@@ -2130,8 +2136,8 @@ parentheses.
-if x == (T{a,b,c}[i]) { ... } -if (x == T{a,b,c}[i]) { ... } +if x == (T{a,b,c}[i]) { … } +if (x == T{a,b,c}[i]) { … }
@@ -2335,11 +2341,11 @@ p.M0 // ((*p).T0).M0 - +-->
a
of type S
where S
is a run-time panic occurs
@@ -2396,7 +2402,7 @@ where M
is a map type:
x
,
a[x]
is the map value with key x
and the type of a[x]
is the value type of M
nil
or does not contain such an entry,
a[x]
is the zero value
for the value type of M
-Similarly, if an assignment to a map has the special form +Similarly, if an assignment to a map element has the special form
@@ -2439,6 +2445,11 @@ the entry for key@@ -3557,17 +3592,13 @@ begins. Communication blocks until the send can proceed, at which point the value is transmitted on the channel. A send on an unbuffered channel can proceed if a receiver is ready. A send on a buffered channel can proceed if there is room in the buffer. +A send on ax
is deleted from the map; if a regular assignment to an element of the map. ++Assigning to an element of a
+nil
map causes a +run-time panic. +Slices
@@ -2559,11 +2570,11 @@ Given an expressionf
of function type-f(a1, a2, ... an) +f(a1, a2, … an)-calls
f
with argumentsa1, a2, ... an
. +callsf
with argumentsa1, a2, … an
. Except for one special case, arguments must be single-valued expressions assignable to the parameter types ofF
and are evaluated before the function is called. @@ -2642,7 +2653,7 @@ arguments bound to the final parameter and may differ for each call site. Given the function and call-func Greeting(prefix string, who ... string) +func Greeting(prefix string, who ...string) Greeting("hello:", "Joe", "Anna", "Eileen")@@ -2693,42 +2704,39 @@ unary_op = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .Comparisons are discussed elsewhere. For other binary operators, the operand types must be identical -unless the operation involves channels, shifts, or untyped constants. +unless the operation involves shifts or untyped constants. For operations involving constants only, see the section on constant expressions.
-In a channel send, the first operand is always a channel and the second -must be a value assignable -to the channel's element type. -
- --Except for shift operations, -if one operand is an untyped constant +Except for shift operations, if one operand is an untyped constant and the other operand is not, the constant is converted to the type of the other operand.
-The right operand in a shift operation must have unsigned integer type +The right operand in a shift expression must have unsigned integer type or be an untyped constant that can be converted to unsigned integer type. -
- --If the left operand of a non-constant shift operation is an untyped constant, -the type of constant is what it would be if the shift operation were replaced by -the left operand alone. +If the left operand of a non-constant shift expression is an untyped constant, +the type of the constant is what it would be if the shift expression were +replaced by its left operand alone; the type is
int
if it cannot +be determined from the context (for instance, if the shift expression is an +operand in a comparison against an untyped constant).var s uint = 33 -var i = 1<<s // 1 has type int -var j = int32(1<<s) // 1 has type int32; j == 0 -var u = uint64(1<<s) // 1 has type uint64; u == 1<<33 -var f = float32(1<<s) // illegal: 1 has type float32, cannot shift -var g = float32(1<<33) // legal; 1<<33 is a constant shift operation; g == 1<<33 +var i = 1<<s // 1 has type int +var j int32 = 1<<s // 1 has type int32; j == 0 +var k = uint64(1<<s) // 1 has type uint64; k == 1<<33 +var m int = 1.0<<s // legal: 1.0 has type int +var n = 1.0<<s != 0 // legal: 1.0 has type int; n == false if ints are 32bits in size +var o = 1<<s == 2<<s // legal: 1 and 2 have type int; o == true if ints are 32bits in size +var p = 1<<s == 1<<33 // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int +var u = 1.0<<s // illegal: 1.0 has type float64, cannot shift +var v float32 = 1<<s // illegal: 1 has type float32, cannot shift +var w int64 = 1.0<<33 // legal: 1.0<<33 is a constant shift expressionOperator precedence
@@ -2808,15 +2816,18 @@ s += " and good bye" String addition creates a new string by concatenating the operands.-For integer values,
/
and%
satisfy the following relationship: +For two integer valuesx
andy
, the integer quotient +q = x / y
and remainderr = x % y
satisfy the following +relationships:-(a / b) * b + a % b == a +x = q*y + r and |r| < |y|-with
(a / b)
truncated towards zero. +withx / y
truncated towards zero +("truncated division").@@ -2827,6 +2838,20 @@ with+(a / b)
truncated towards zero. -5 -3 1 -2+As an exception to this rule, if the dividend
+ +x
is the most +negative value for the int type ofx
, the quotient +q = x / -1
is equal tox
(andr = 0
). ++ x, q +int8 -128 +int16 -32768 +int32 -2147483648 +int64 -9223372036854775808 ++If the divisor is zero, a run-time panic occurs. If the dividend is positive and the divisor is a constant power of 2, @@ -2843,8 +2868,8 @@ be replaced by a bitwise "and" operation:
The shift operators shift the left operand by the shift count specified by the right operand. They implement arithmetic shifts if the left operand is a signed -integer and logical shifts if it is an unsigned integer. The shift count must -be an unsigned integer. There is no upper limit on the shift count. Shifts behave +integer and logical shifts if it is an unsigned integer. +There is no upper limit on the shift count. Shifts behave as if the left operand is shifted
n
times by 1 for a shift count ofn
. As a result,x << 1
is the same asx*2
@@ -3025,6 +3050,7 @@ For an operandch
of channel type, the value of the receive operation<-ch
is the value received from the channelch
. The type of the value is the element type of the channel. The expression blocks until a value is available. +Receiving from anil
channel blocks forever.@@ -3052,17 +3078,12 @@ or is a zero value returned because the channel is closed and empty (- +-->false
). --Receiving from a
- - +-->nil
channel causes a -run-time panic. -Method expressions
@@ -3360,21 +3381,35 @@ respectively. Except for shift operations, if the operands of a binary operation are an untyped integer constant and an untyped floating-point constant, the integer constant is converted to an untyped floating-point constant (relevant for/
and%
). -Similarly, -untyped integer or floating-point constants may be used as operands +Similarly, untyped integer or floating-point constants may be used as operands wherever it is legal to use an operand of complex type; the integer or floating point constant is converted to a complex constant with a zero imaginary part.-Applying an operator to untyped constants results in an untyped +A constant comparison always yields +a constant of type
+bool
. If the left operand of a constant +shift expression is an untyped constant, the +result is an integer constant; otherwise it is a constant of the same +type as the left operand, which must be of integer type +(§Arithmetic operators). +Applying all other operators to untyped constants results in an untyped constant of the same kind (that is, a boolean, integer, floating-point, -complex, or string constant), except for -comparison operators, which result in -a constant of typebool
. +complex, or string constant).+const a = 2 + 3.0 // a == 5.0 (floating-point constant) +const b = 15 / 4 // b == 3 (integer constant) +const c = 15 / 4.0 // c == 3.75 (floating-point constant) +const d = 1 << 3.0 // d == 8 (integer constant) +const e = 1.0 << 3 // e == 8 (integer constant) +const f = int32(1) << 33 // f == 0 (type int32) +const g = float64(2) >> 1 // illegal (float64(2) is a typed floating-point constant) +const h = "foo" > "bar" // h == true (type bool) ++Imaginary literals are untyped complex constants (with zero real part) and may be combined in binary @@ -3431,7 +3466,7 @@ int8(^1) // same as int8(-2) ^int8(1) // same as -1 ^ int8(1) = -2
Order of evaluation
@@ -3522,10 +3557,9 @@ Error: log.Panic("error encountered")Function calls, method calls, and receive operations -can appear in statement context. +can appear in statement context. Such statements may be parenthesized.
-ExpressionStmt = Expression .@@ -3534,6 +3568,7 @@ ExpressionStmt = Expression . h(x+y) f.Close() <-ch +(<-ch)
nil
channel blocks forever.
ch <- 3-
-Sending to a nil
channel causes a
-run-time panic.
-
Each left-hand side operand must be addressable, -a map index expression, -or the blank identifier. +a map index expression, or the blank identifier. +Operands may be parenthesized.
x = 1 *p = f() a[i] = 23 -k = <-ch +(k) = <-ch // same as: k = <-ch
@@ -3966,10 +3997,14 @@ As with an assignment, the operands on the left must be addressable 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. +If the second iteration variable is the blank identifier, +the range clause is equivalent to the same clause with only the first variable present.
-The range expression is evaluated once before beginning the loop. +The range expression is evaluated once before beginning the loop +except if the expression is an array, in which case, depending on +the expression, it might not be evaluated (see below). Function calls on the left are evaluated once per iteration. For each iteration, iteration values are produced as follows:
@@ -3985,8 +4020,11 @@ channel c chan E element e Ea
, the index iteration
+values are produced in increasing order, starting at element index 0. As a special
+case, if only the first iteration variable is present, the range loop produces
+iteration values from 0 up to len(a)
and does not index into the array
+or slice itself. For a nil
slice, the number of iterations is 0.
nil
, the number of iterations is 0.
close
).
+the channel until the channel is closed. If the channel
+is nil
, the range expression blocks forever.
+var testdata *struct { + a *[7]int +} +for i, _ := range testdata.a { + // testdata.a is never evaluated; len(testdata.a) is constant + // i ranges from 0 to 6 + f(i) +} + var a [10]string m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6} - for i, s := range a { // type of i is int // type of s is string @@ -4047,6 +4094,11 @@ for key, val = range m { } // key == last map key encountered in iteration // val == map[key] + +var ch chan Work = producer() +for w := range ch { + doWork(w) +}@@ -4131,7 +4183,7 @@ case i1 = <-c1: print("received ", i1, " from c1\n") case c2 <- i2: print("sent ", i2, " to c2\n") -case i3, ok := <-c3: +case i3, ok := (<-c3): // same as: i3, ok := <-c3 if ok { print("received ", i3, " from c3\n") } else { @@ -4229,7 +4281,7 @@ func (devnull) Write(p []byte) (n int, _ os.Error) { Regardless of how they are declared, all the result values are initialized to the zero values for their type (§The zero value) upon entry to the function. - +-->
is erroneous because the jump to label L
skips
the creation of v
.
-
+-->
int
-Call Argument type Result
+Call Argument type Result
-len(s) string type string length in bytes
- [n]T, *[n]T array length (== n)
- []T slice length
- map[K]T map length (number of defined keys)
- chan T number of elements queued in channel buffer
+len(s) string type string length in bytes
+ [n]T, *[n]T array length (== n)
+ []T slice length
+ map[K]T map length (number of defined keys)
+ chan T number of elements queued in channel buffer
-cap(s) [n]T, *[n]T array length (== n)
- []T slice capacity
- chan T channel buffer capacity
+cap(s) [n]T, *[n]T array length (== n)
+ []T slice capacity
+ chan T channel buffer capacity
@@ -4449,20 +4501,17 @@ The length and capacity of a nil
slice, map, or channel are 0.
-The expression
-len(s)
is a
-constant if s
is a string constant.
-The expressions
-len(s)
and
-cap(s)
are
-constants if s
is an (optionally parenthesized)
-identifier or
-qualified identifier
-denoting an array or pointer to array.
-Otherwise invocations of len
and cap
are not
-constant.
+The expression len(s)
is constant if
+s
is a string constant. The expressions len(s)
and
+cap(s)
are constants if the type of s
is an array
+or pointer to an array and the expression s
does not contain
+channel receives or
+function calls; in this case s
is not evaluated.
+Otherwise, invocations of len
and cap
are not
+constant and s
is evaluated.
+
Allocation
@@ -4575,7 +4624,7 @@ a source src
to a destination dst
and returns the
number of elements copied. Source and destination may overlap.
Both arguments must have identical element type T
and must be
assignable to a slice of type []T
.
-The number of arguments copied is the minimum of
+The number of elements copied is the minimum of
len(src)
and len(dst)
.
As a special case, copy
also accepts a destination argument assignable
to type []byte
with a source argument of a string type.
@@ -4850,7 +4899,7 @@ package main
import "fmt"
-// Send the sequence 2, 3, 4, ... to channel 'ch'.
+// Send the sequence 2, 3, 4, … to channel 'ch'.
func generate(ch chan<- int) {
for i := 2; ; i++ {
ch <- i // Send 'i' to channel 'ch'.
@@ -4890,7 +4939,7 @@ func main() {
The zero value
When memory is allocated to store a value, either through a declaration
-or make()
or new()
call,
+or a call of make
or new
,
and no explicit initialization is provided, the memory is
given a default initialization. Each element of such a value is
set to the zero value for its type: false
for booleans,
@@ -4948,7 +4997,7 @@ func init()
defined in its source.
A package may contain multiple
-init()
functions, even
+init
functions, even
within a single source file; they execute
in unspecified order.
@@ -4978,8 +5027,8 @@ program is complete. Therefore, all initialization code is run in a single
goroutine.
-An init()
function cannot be referred to from anywhere
-in a program. In particular, init()
cannot be called explicitly,
+An init
function cannot be referred to from anywhere
+in a program. In particular, init
cannot be called explicitly,
nor can a pointer to init
be assigned to a function variable.
@@ -5001,7 +5050,7 @@ arguments and returns no value.
-func main() { ... }
+func main() { … }
@@ -5151,5 +5200,8 @@ The following minimal alignment properties are guaranteed:
Implementation differences - TODO
- - Implementation does not honor the restriction on goto statements and targets (no intervening declarations).
+ - The restriction on
goto
statements and targets (no intervening declarations) is not honored.
+ len(a)
is only a constant if a
is a (qualified) identifier denoting an array or pointer to an array.
+ nil
maps are not treated like empty maps.
+ - Trying to send/receive from a
nil
channel causes a run-time panic.
--
cgit v1.2.3