diff --git a/doc/go_spec.html b/doc/go_spec.html index eef4921d3e9..01770395fde 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -1533,6 +1533,9 @@ no identifier may be declared in both the file and package block.
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.
@@ -4014,7 +4017,7 @@ precision.-Order of evaluation
-At package level, initialization dependencies +At package level, initialization dependencies determine the evaluation order of individual initialization expressions in variable declarations. Otherwise, when evaluating the operands of an @@ -5907,62 +5910,125 @@ The same would also be true after var t T
-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
+Within a package, package-level variables are initialized according
+to their dependencies: if a variable x
depends on
+a variable y
, 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 variable y
;
+if so, x
depends on y
.
+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 +
+-func init() +var ( + a = c + b + b = f() + c = f() + d = 3 +) + +func f() int { + d++ + return d +}+
-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.
+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
).
-Within a package, package-level variables are initialized,
-and constant values are determined, according to
-order of reference: if the initializer of A
-depends on B
, A
-will be set after B
.
-Dependency analysis does not depend on the actual values
-of the items being initialized, only on their appearance
-in the source.
-A
-depends on B
if the value of A
-contains a mention of B
, contains a value
-whose initializer
-mentions B
, or mentions a function that
-mentions B
, 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 if A
's initializer calls a function defined
-in another package that refers to B
.
+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 unspecified order.
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.
@@ -5983,18 +6049,6 @@ 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.
-