diff --git a/doc/go_spec.html b/doc/go_spec.html index eef4921d3e..01770395fd 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.
-