From 8a39ee361feb9bf46d728ff1ba4f07ca1d9610b1 Mon Sep 17 00:00:00 2001
From: Michael Stapelberg
This is a reference manual for the Go programming language. For
-more information and other documents, see http://golang.org.
+more information and other documents, see http://golang.org.
@@ -120,7 +120,7 @@ unicode_digit = /* a Unicode code point classified as "Decimal Digit" */ .
-In The Unicode Standard 6.2,
+In The Unicode Standard 6.3,
Section 4.5 "General Category"
defines a set of character categories. Go treats
those characters in category Lu, Ll, Lt, Lm, or Lo as Unicode letters,
@@ -471,7 +471,7 @@ string composed of the uninterpreted (implicitly UTF-8-encoded) characters
between the quotes;
in particular, backslashes have no special meaning and the string may
contain newlines.
-Carriage returns inside raw string literals
+Carriage return characters ('\r') inside raw string literals
are discarded from the raw string value.
@@ -674,7 +674,8 @@ types, the dynamic type is always the static type.
Each type
-A type may have a method set associated with it
-(§Interface types, §Method declarations).
+A type may have a method set associated with it.
The method set of an interface type is its interface.
-The method set of any other type
@@ -817,8 +818,8 @@ ElementType = Type .
-The length is part of the array's type; it must evaluate to a non-
-negative constant representable by a value
+The length is part of the array's type; it must evaluate to a
+non-negative constant representable by a value
of type
As with all method sets, in an interface type, each method must have a
-unique name.
+unique
+non-blank name.
-A channel provides a mechanism for two concurrently executing functions
-to synchronize execution and communicate by passing a value of a
-specified element type.
+A channel provides a mechanism for
+concurrently executing functions
+to communicate by
+sending and
+receiving
+values of a specified element type.
The value of an uninitialized channel is
-The T
has an underlying type: If T
-is a predeclared type or a type literal, the corresponding underlying
+is one of the predeclared boolean, numeric, or string types, or a type literal,
+the corresponding underlying
type is T
itself. Otherwise, T
's underlying type
is the underlying type of the type to which T
refers in its
type declaration.
@@ -695,19 +696,19 @@ and T4
is []T1
.
Method sets
T
-consists of all methods with receiver type T
.
-The method set of the corresponding pointer type *T
-is the set of all methods with receiver *T
or T
+The method set of any other type T
consists of all
+methods declared with receiver type T
.
+The method set of the corresponding pointer type *T
+is the set of all methods declared with receiver *T
or T
(that is, it also contains the method set of T
).
Further rules apply to structs containing anonymous fields, as described
in the section on struct types.
Any other type has an empty method set.
In a method set, each method must have a
-unique method name.
+unique
+non-blank method name.
int
.
The length of array a
can be discovered
using the built-in function len
.
@@ -1009,7 +1010,7 @@ A field declaration may be followed by an optional string literal tag,
which becomes an attribute for all the fields in the corresponding
field declaration. The tags are made
visible through a reflection interface
-and take part in type identity for structs
+and take part in type identity for structs
but are otherwise ignored.
@@ -1277,20 +1279,23 @@ may be added.
Channel types
nil
.
-ChannelType = ( "chan" [ "<-" ] | "<-" "chan" ) ElementType .
+ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
<-
operator specifies the channel direction,
+The optional <-
operator specifies the channel direction,
send or receive. If no direction is given, the channel is
-bi-directional.
+bidirectional.
A channel may be constrained only to send or only to receive by
conversion or assignment.
make
,
-which takes the channel type and an optional capacity as arguments:
+which takes the channel type and an optional capacity as arguments:
@@ -1325,21 +1330,35 @@ make(chan int, 100)
-The capacity, in number of elements, sets the size of the buffer in the channel. If the
-capacity is greater than zero, the channel is asynchronous: communication operations
-succeed without blocking if the buffer is not full (sends) or not empty (receives),
-and elements are received in the order they are sent.
-If the capacity is zero or absent, the communication succeeds only when both a sender and
-receiver are ready.
+The capacity, in number of elements, sets the size of the buffer in the channel.
+If the capacity is zero or absent, the channel is unbuffered and communication
+succeeds only when both a sender and receiver are ready. Otherwise, the channel
+is buffered and communication succeeds without blocking if the buffer
+is not full (sends) or not empty (receives).
A nil
channel is never ready for communication.
A channel may be closed with the built-in function
-close
; the
-multi-valued assignment form of the
+close
.
+The multi-valued assignment form of the
receive operator
-tests whether a channel has been closed.
+reports whether a received value was sent before
+the channel was closed.
+
+A single channel may be used in
+send statements,
+receive operations,
+and calls to the built-in functions
+cap
and
+len
+by any number of goroutines without further synchronization.
+Channels act as first-in-first-out queues.
+For example, if one goroutine sends values on a channel
+and a second goroutine receives them, the values are
+received in the order sent.
The blank identifier may be used like any other identifier
in a declaration, but it does not introduce a binding and thus is not declared.
+In the package block, the identifier init
may only be used for
+init
function declarations,
+and like the blank identifier it does not introduce a new binding.
@@ -1770,9 +1792,9 @@ last non-empty expression list.A type declaration binds an identifier, the type name, to a new type -that has the same underlying type as -an existing type. The new type is different from -the existing type. +that has the same underlying type as an existing type, +and operations defined for the existing type are also defined for the new type. +The new type is different from the existing type.
@@ -2267,8 +2289,6 @@ Similarly, elements that are addresses of composite literals may elide the&T
when the element type is*T
. - -[...]Point{{1.5, -3.5}, {0, 0}} // same as [...]Point{Point{1.5, -3.5}, Point{0, 0}} [][]int{{1, 2, 3}, {4, 5}} // same as [][]int{[]int{1, 2, 3}, []int{4, 5}} @@ -2278,13 +2298,13 @@ the&T
when the element type is*T
.A parsing ambiguity arises when a composite literal using the -TypeName form of the LiteralType appears between the -keyword and the opening brace of the block of an -"if", "for", or "switch" statement, because the braces surrounding -the expressions in the literal are confused with those introducing -the block of statements. To resolve the ambiguity in this rare case, -the composite literal must appear within -parentheses. +TypeName form of the LiteralType appears as an operand between the +keyword and the opening brace of the block +of an "if", "for", or "switch" statement, and the composite literal +is not enclosed in parentheses, square brackets, or curly braces. +In this rare case, the opening brace of the literal is erroneously parsed +as the one introducing the block of statements. To resolve the ambiguity, +the composite literal must appear within parentheses.
@@ -2692,7 +2712,7 @@ For arrays or strings, the indices are in range if otherwise they are out of range. For slices, the upper index bound is the slice capacitycap(a)
rather than the length. A constant index must be non-negative and representable by a value of type -int
. +int
; for arrays or constant strings, constant indices must also be in range. If both indices are constant, they must satisfylow <= high
. If the indices are out of range at run time, a run-time panic occurs. @@ -2752,7 +2772,7 @@ If the sliced operand is an array, it must be addre The indices are in range if0 <= low <= high <= max <= cap(a)
, otherwise they are out of range. A constant index must be non-negative and representable by a value of type -int
. +int
; for arrays, constant indices must also be in range. If multiple indices are constant, the constants that are present must be in range relative to each other. If the indices are out of range at run time, a run-time panic occurs. @@ -2916,27 +2936,32 @@ There is no distinct method type and there are no method literals.Passing arguments to
...
parameters-If
f
is variadic with final parameter type...T
, -then within the function the argument is equivalent to a parameter of type -[]T
. At each call off
, the argument -passed to the final parameter is -a new slice of type[]T
whose successive elements are -the actual arguments, which all must be assignable -to the typeT
. The length of the slice is therefore the number of -arguments bound to the final parameter and may differ for each call site. +Iff
is variadic with a final +parameterp
of type...T
, then withinf
+the type ofp
is equivalent to type[]T
. +Iff
is invoked with no actual arguments forp
, +the value passed top
isnil
. +Otherwise, the value passed is a new slice +of type[]T
with a new underlying array whose successive elements +are the actual arguments, which all must be assignable +toT
. The length and capacity of the slice is therefore +the number of arguments bound top
and may differ for each +call site.-Given the function and call +Given the function and calls
func Greeting(prefix string, who ...string) +Greeting("nobody") Greeting("hello:", "Joe", "Anna", "Eileen")within
Greeting
,who
will have the value -[]string{"Joe", "Anna", "Eileen"}
+nil
in the first call, and +[]string{"Joe", "Anna", "Eileen"}
in the second.@@ -3385,7 +3410,8 @@ and the type of the receive operation is the element type of the channel. The expression blocks until a value is available. Receiving from a
nil
channel blocks forever. A receive operation on a closed channel can always proceed -immediately, yielding the element type's zero value. +immediately, yielding the element type's zero value +after any previously sent values have been received.@@ -3929,7 +3955,7 @@ an untyped complex constant.const ic = complex(0, c) // ic == 3.75i (untyped complex constant) -const iΘ = complex(0, Θ) // iΘ == 1.5i (type complex128) +const iΘ = complex(0, Θ) // iΘ == 1i (type complex128)@@ -3992,8 +4018,11 @@ precision.
Order of evaluation
-When evaluating the operands of an expression, -assignment, or +At package level, initialization dependencies +determine the evaluation order of individual initialization expressions in +variable declarations. +Otherwise, when evaluating the operands of an +expression, assignment, or return statement, all function calls, method calls, and communication operations are evaluated in lexical left-to-right @@ -4001,7 +4030,7 @@ order.
-For example, in the assignment +For example, in the (function-local) assignment
y[f()], ok = g(h(), i()+x[j()], <-c), k() @@ -4018,11 +4047,33 @@ ofy
is not specified.a := 1 f := func() int { a++; return a } -x := []int{a, f()} // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified -m := map[int]int{a: 1, a: 2} // m may be {2: 1} or {2: 2}: evaluation order between the two map assignments is not specified -m2 := map[int]int{a: f()} // m2 may be {2: 3} or {3: 3}: evaluation order between the key and the value is not specified +x := []int{a, f()} // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified +m := map[int]int{a: 1, a: 2} // m may be {2: 1} or {2: 2}: evaluation order between the two map assignments is not specified +n := map[int]int{a: f()} // n may be {2: 3} or {3: 3}: evaluation order between the key and the value is not specified++At package level, initialization dependencies override the left-to-right rule +for individual initialization expressions, but not for operands within each +expression: +
+ ++var a, b, c = f() + v(), g(), sqr(u()) + v() + +func f() int { return c } +func g() int { return a } +func sqr(x int) int { return x*x } + +// functions u and v are independent of all other variables and functions ++ ++The function calls happen in the order +
+u()
,sqr()
,v()
, +f()
,v()
, andg()
. +Floating-point operations within a single expression are evaluated according to the associativity of the operators. Explicit parentheses affect the evaluation @@ -4209,22 +4260,8 @@ A send on a closed channel proceeds by causing a run- A send on a
-nil
channel blocks forever.-Channels act as first-in-first-out queues. -For example, if a single goroutine sends on a channel values -that are received by a single goroutine, the values are received in the order sent. -
- --A single channel may be used for send and receive -operations and calls to the built-in functions -
-cap
and -len
-by any number of goroutines without further synchronization. --ch <- 3 +ch <- 3 // send value 3 to channel ch@@ -4459,8 +4496,8 @@ If no case matches and there is a "default" case, its statements are executed. There can be at most one default case and it may appear anywhere in the "switch" statement. -A missing switch expression is equivalent to -the expressiontrue
. +A missing switch expression is equivalent to the boolean value +true
.@@ -4625,7 +4662,8 @@ Condition = Expression . In its simplest form, a "for" statement specifies the repeated execution of a block as long as a boolean condition evaluates to true. The condition is evaluated before each iteration. -If the condition is absent, it is equivalent totrue
. +If the condition is absent, it is equivalent to the boolean value +true
.@@ -4662,7 +4700,8 @@ only if the block was executed). Any element of the ForClause may be empty but the semicolons are required unless there is only a condition. -If the condition is absent, it is equivalent totrue
. +If the condition is absent, it is equivalent to the boolean value +true
.@@ -4844,8 +4883,12 @@ go func(ch chan<- bool) { for { sleep(10); ch <- true; }} (c)Select statements
-A "select" statement chooses which of a set of possible communications -will proceed. It looks similar to a "switch" statement but with the +A "select" statement chooses which of a set of possible +send or +receive +operations will proceed. +It looks similar to a +"switch" statement but with the cases all referring to communication operations.
@@ -4858,41 +4901,63 @@ RecvExpr = Expression .-RecvExpr must be a receive operation. -For all the cases in the "select" -statement, the channel expressions are evaluated in top-to-bottom order, along with -any expressions that appear on the right hand side of send statements. -A channel may be
+nil
, -which is equivalent to that case not -being present in the select statement -except, if a send, its expression is still evaluated. -If any of the resulting operations can proceed, one of those is -chosen and the corresponding communication and statements are -evaluated. Otherwise, if there is a default case, that executes; -if there is no default case, the statement blocks until one of the communications can -complete. There can be at most one default case and it may appear anywhere in the -"select" statement. -If there are no cases with non-nil
channels, -the statement blocks forever. -Even if the statement blocks, -the channel and send expressions are evaluated only once, -upon entering the select statement. +A case with a RecvStmt may assign the result of a RecvExpr to one or +two variables, which may be declared using a +short variable declaration. +The RecvExpr must be a (possibly parenthesized) receive operation. +There can be at most one default case and it may appear anywhere +in the list of cases.-Since all the channels and send expressions are evaluated, any side -effects in that evaluation will occur for all the communications -in the "select" statement. +Execution of a "select" statement proceeds in several steps:
+ ++
+- +For all the cases in the statement, the channel operands of receive operations +and the channel and right-hand-side expressions of send statements are +evaluated exactly once, in source order, upon entering the "select" statement. +The result is a set of channels to receive from or send to, +and the corresponding values to send. +Any side effects in that evaluation will occur irrespective of which (if any) +communication operation is selected to proceed. +Expressions on the left-hand side of a RecvStmt with a short variable declaration +or assignment are not yet evaluated. +
+ +- +If one or more of the communications can proceed, +a single one that can proceed is chosen via a uniform pseudo-random selection. +Otherwise, if there is a default case, that case is chosen. +If there is no default case, the "select" statement blocks until +at least one of the communications can proceed. +
+ +- +Unless the selected case is the default case, the respective communication +operation is executed. +
+ +- +If the selected case is a RecvStmt with a short variable declaration or +an assignment, the left-hand side expressions are evaluated and the +received value (or values) are assigned. +
+ +- +The statement list of the selected case is executed. +
+-If multiple cases can proceed, a uniform pseudo-random choice is made to decide -which single communication will execute. -
-The receive case may declare one or two new variables using a -short variable declaration. +Since communication on
nil
channels can never proceed, +a select with onlynil
channels and no default case blocks forever.-var c, c1, c2, c3 chan int +var a []int +var c, c1, c2, c3, c4 chan int var i1, i2 int select { case i1 = <-c1: @@ -4905,6 +4970,10 @@ case i3, ok := (<-c3): // same as: i3, ok := <-c3 } else { print("c3 is closed\n") } +case a[f()] = <-c4: + // same as: + // case t := <-c4 + // a[f()] = t default: print("no communication\n") } @@ -5002,6 +5071,21 @@ function. A "return" statement that specifies results sets the result parameters any deferred functions are executed. ++Implementation restriction: A compiler may disallow an empty expression list +in a "return" statement if a different entity (constant, type, or variable) +with the same name as a result parameter is in +scope at the place of the return. +
+ ++func f(n int) (res int, err error) { + if _, err := f(n-1); err != nil { + return // invalid return statement: err is shadowed + } + return +} +Break statements
@@ -5009,7 +5093,8 @@ any deferred functions are executed. A "break" statement terminates execution of the innermost "for", "switch", or -"select" statement. +"select" statement +within the same function.@@ -5043,6 +5128,7 @@ OuterLoop:A "continue" statement begins the next iteration of the innermost "for" loop at its post statement. +The "for" loop must be within the same function.
@@ -5070,7 +5156,8 @@ RowLoop:-Goto statements
-A "goto" statement transfers control to the statement with the corresponding label. +A "goto" statement transfers control to the statement with the corresponding label +within the same function.
@@ -5263,7 +5350,7 @@ At any time the following relationship holds:@@ -5669,7 +5766,7 @@ If the PackageName is omitted, it defaults to the identifier specified in the If an explicit period (The length of a
nil
slice, map or channel is 0. -The capacity of anil
slice and channel is 0. +The capacity of anil
slice or channel is 0.@@ -5271,12 +5358,22 @@ The expression
+len(s)
is constant ifs
is a string constant. The expressionslen(s)
andcap(s)
are constants if the type ofs
is an array or pointer to an array and the expressions
does not contain -channel receives or +channel receives or (non-constant) function calls; in this cases
is not evaluated. Otherwise, invocations oflen
andcap
are not constant ands
is evaluated.+const ( + c1 = imag(2i) // imag(2i) = 2.0 is a constant + c2 = len([10]float64{2}) // [10]float64{2} contains no function calls + c3 = len([10]float64{c1}) // [10]float64{c1} contains no function calls + c4 = len([10]float64{imag(2i)}) // imag(2i) is a constant and no function call is issued + c5 = len([10]float64{imag(z)}) // invalid: imag(x) is a (non-constant) function call +) +var z complex128 +Allocation
@@ -5327,8 +5424,8 @@ make(T, n, m) slice slice of type T with length n and capacity m make(T) map map of type T make(T, n) map map of type T with initial space for n elements -make(T) channel synchronous channel of type T -make(T, n) channel asynchronous channel of type T, buffer size n +make(T) channel unbuffered channel of type T +make(T, n) channel buffered channel of type T, buffer size n.
) appears instead of a name, all the package's exported identifiers declared in that package's package block will be declared in the importing source -file's file block and can be accessed without a qualifier. +file's file block and must be accessed without a qualifier.@@ -5681,7 +5778,7 @@ package and may be relative to a repository of installed packages.
Implementation restriction: A compiler may restrict ImportPaths to non-empty strings using only characters belonging to -Unicode's +Unicode's L, M, N, P, and S general categories (the Graphic characters without spaces) and may also exclude the characters
@@ -5817,62 +5914,126 @@ The same would also be true after var t T!"#$%&'()*,:;<=>?[\]^`{|}
@@ -5693,7 +5790,7 @@ Assume we have compiled a package containing the package clausepackage math
, which exports functionSin
, and installed the compiled package in the file identified by"lib/math"
. -This table illustrates howSin
may be accessed in files +This table illustrates howSin
is accessed in files that import the package after the various types of import declaration.Program execution
+Package initialization
-A package with no imports is initialized by assigning initial values to -all its package-level variables -and then calling any -package-level function with the name and signature of -
--func init() ---defined in its source. -A package-scope or file-scope identifier -with name
-init
may only be -declared to be a function with this signature. -Multiple such functions may be defined, even -within a single source file; they execute -in unspecified order. --Within a package, package-level variables are initialized, -and constant values are determined, according to -order of reference: if the initializer of
+ +A
-depends onB
,A
-will be set afterB
. -Dependency analysis does not depend on the actual values -of the items being initialized, only on their appearance -in the source. -A
-depends onB
if the value ofA
-contains a mention ofB
, contains a value -whose initializer -mentionsB
, or mentions a function that -mentionsB
, recursively. -It is an error if such dependencies form a cycle. -If two items are not interdependent, they will be initialized -in the order they appear in the source, possibly in multiple files, -as presented to the compiler. -Since the dependency analysis is done per package, it can produce -unspecified results ifA
's initializer calls a function defined -in another package that refers toB
. +Within a package, package-level variables are initialized according +to their dependencies: if a variablex
depends on +a variabley
,x
will be initialized after +y
. ++Dependency analysis does not rely on the actual values of the +variables, only on lexical references to them in the source, +analyzed transitively. For instance, a variable
+ +x
's +initialization expression +may refer to a function whose body refers to variabley
; +if so,x
depends ony
. +Specifically: +
m
is a
+method value or
+method expression of the form
+t.m
, where the (static) type of t
is
+not an interface type, and the method m
is in the
+method set of t
.
+It is immaterial whether the resulting function value
+t.m
is invoked.
+x
depends on a variable
+y
if x
's initialization expression or body
+(for functions and methods) contains a reference to y
+or to a function or method that depends on y
.
++Dependency analysis is performed per package; only references referring +to variables, functions, and methods declared in the current package +are considered. +It is an error if variable dependencies form a cycle +(but dependency cycles containing no variables are permitted). +If two variables are independent of each other, +they are initialized in the order they are declared +in the source, possibly in multiple files, as presented to the compiler. +
+ ++For example, given the declarations +
+ ++var ( + a = c + b + b = f() + c = f() + d = 3 +) + +func f() int { + d++ + return d +} ++ +
+the initialization order is d
, b
, c
, a
.
+Since b
and c
are independent of each other, they are
+initialized in declaration order (b
before c
).
+
+Variables may also be initialized using functions named init
+declared in the package block, with no arguments and no result parameters.
+func init() { … } ++
-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.
+Multiple such functions may be defined, even within a single
+source file. The init
identifier is not
+declared and thus
+init
functions cannot be referred to from anywhere
+in a program.
+A package with no imports is initialized by assigning initial values
+to all its package-level variables followed by calling all init
+functions in the order they appear in the source, possibly in multiple files,
+as presented to the compiler.
If a package has imports, the imported packages are initialized
before initializing the package itself. If multiple packages import
-a package P
, P
will be initialized only once.
+a package, the imported package will be initialized only once.
+The importing of packages, by construction, guarantees that there
+can be no cyclic initialization dependencies.
-The importing of packages, by construction, guarantees that there can
-be no cyclic dependencies in initialization.
+Package initialization—variable initialization and the invocation of
+init
functions—happens in a single goroutine,
+sequentially, one package at a time.
+An init
function may launch other goroutines, which can run
+concurrently with the initialization code. However, initialization
+always sequences
+the init
functions: it will not invoke the next one
+until the previous one has returned.
A complete program is created by linking a single, unimported package called the main package with all the packages it imports, transitively. @@ -5889,22 +6050,10 @@ func main() { … }
Program execution begins by initializing the main package and then
invoking the function main
.
-When the function main
returns, the program exits.
+When that function invocation returns, the program exits.
It does not wait for other (non-main
) goroutines to complete.
-Package initialization—variable initialization and the invocation of
-init
functions—happens in a single goroutine,
-sequentially, one package at a time.
-An init
function may launch other goroutines, which can run
-concurrently with the initialization code. However, initialization
-always sequences
-the init
functions: it will not start the next
-init
until
-the previous one has returned.
-
-- cgit v1.2.3