mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
new scope rules
DELTA=137 (50 added, 24 deleted, 63 changed) OCL=33476 CL=33553
This commit is contained in:
parent
11e4db7c12
commit
0a162a1433
1 changed files with 102 additions and 76 deletions
178
doc/go_spec.html
178
doc/go_spec.html
|
@ -10,9 +10,7 @@ Open issues:
|
|||
|
||||
Todo's:
|
||||
[ ] need language about function/method calls and parameter passing rules
|
||||
[ ] clarify new scope rules for package-level identifiers
|
||||
[ ] clarify scope of identifiers denoting imported packages (file scope)
|
||||
[ ] package identifier not in any scope
|
||||
[ ] need to say something about "scope" of selectors?
|
||||
[ ] clarify what a field name is in struct declarations
|
||||
(struct{T} vs struct {T T} vs struct {t T})
|
||||
[ ] need explicit language about the result type of operations
|
||||
|
@ -1226,74 +1224,119 @@ They will be equal only if they have the same dynamic type and the underlying va
|
|||
<hr/>
|
||||
|
||||
|
||||
<h2>Declarations and Scope</h2>
|
||||
<h2>Blocks</h2>
|
||||
|
||||
<p>
|
||||
A declaration binds an identifier to a language entity such as
|
||||
a variable or function and specifies properties such as its type.
|
||||
Every identifier in a program must be declared.
|
||||
A <i>block</i> is a sequence of declarations and statements within matching
|
||||
brace brackets.
|
||||
</p>
|
||||
|
||||
<pre class="ebnf">
|
||||
Declaration = ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl .
|
||||
Block = "{" StatementList "}" .
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The <i>scope</i> of an identifier is the extent of source text within which the
|
||||
identifier denotes the bound entity. No identifier may be declared twice in a
|
||||
single scope, but inner blocks can declare a new entity with the same
|
||||
identifier, in which case the scope created by the outer declaration excludes
|
||||
that created by the inner.
|
||||
</p>
|
||||
<p>
|
||||
There are levels of scoping in effect before each source file is compiled.
|
||||
In order from outermost to innermost:
|
||||
</p>
|
||||
<ol>
|
||||
<li>The <i>universe</i> scope contains all predeclared identifiers.</li>
|
||||
<li>An implicit scope contains only the package name.</li>
|
||||
<li>The <i>package-level</i> scope surrounds all declarations at the
|
||||
top level of the file, that is, outside the body of any
|
||||
function or method. That scope is shared across all
|
||||
source files within the package (§Packages), allowing
|
||||
package-level identifiers to be shared between source
|
||||
files.</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
The scope of an identifier depends on the entity declared:
|
||||
In addition to explicit blocks in the source code, there are implicit blocks:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li> The scope of predeclared identifiers is the universe scope.</li>
|
||||
<li>The <i>universe block</i> encompasses all Go source text.</li>
|
||||
|
||||
<li> The scope of an identifier denoting a type, function or package
|
||||
extends from the point of the identifier in the declaration
|
||||
to the end of the innermost surrounding block.</li>
|
||||
<li>Each package (§Packages) has a <i>package block</i> containing all
|
||||
Go source text for that package.</li>
|
||||
|
||||
<li> The scope of a constant or variable extends textually from
|
||||
the end of its declaration to the end of the innermost
|
||||
surrounding block. If the variable is declared in the
|
||||
<i>init</i> statement of an <code>if</code>, <code>for</code>,
|
||||
or <code>switch </code> statement, the
|
||||
innermost surrounding block is the block associated
|
||||
with that statement.</li>
|
||||
<li>Each file has a <i>file block</i> containing all Go source text
|
||||
in that file.</li>
|
||||
|
||||
<li> The scope of a parameter or result is the body of the
|
||||
corresponding function.</li>
|
||||
<li>Each <code>if</code>, <code>for</code>, and <code>switch</code>
|
||||
statement is considered to be in its own implicit block.</li>
|
||||
|
||||
<li> The scope of a field or method is selectors for the
|
||||
corresponding type containing the field or method (§Selectors).</li>
|
||||
|
||||
<li> The scope of a label is a special scope emcompassing
|
||||
the body of the innermost surrounding function, excluding
|
||||
nested functions. Labels do not conflict with non-label identifiers.</li>
|
||||
<li>Each case or type case clause in a <code>switch</code> statement,
|
||||
and each communication clause in a <code>select</code> statement
|
||||
acts as an implicit block.</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
Blocks nest and influence scoping (§Declarations and Scope).
|
||||
</p>
|
||||
|
||||
|
||||
<h2>Declarations and Scope</h2>
|
||||
|
||||
<p>
|
||||
A declaration binds an identifier to a constant, type, variable, function, or package.
|
||||
Every identifier in a program must be declared.
|
||||
No identifier may be declared twice in the same block, and
|
||||
no identifier may be declared in both the file and package block.
|
||||
</p>
|
||||
|
||||
<pre class="ebnf">
|
||||
Declaration = ConstDecl | TypeDecl | VarDecl .
|
||||
TopLevelDecl = Declaration | FunctionDecl | MethodDecl .
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The <i>scope</i> of a declared identifier is the extent of source text in which
|
||||
the identifier denotes the specified constant, type, variable, function, or package.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Go is lexically scoped using blocks:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>The scope of a predeclared identifier is the universe block.</li>
|
||||
|
||||
<li>The scope of an identifier denoting a constant, type, variable,
|
||||
or function declared at top level (outside any function) is the
|
||||
package block.</li>
|
||||
|
||||
<li>The scope of an imported package identifier is the file block
|
||||
of the file containing the import declaration.</li>
|
||||
|
||||
<li>The scope of an identifier denoting a function parameter or
|
||||
result variable is the function body.</li>
|
||||
|
||||
<li>The scope of a constant or variable identifier declared
|
||||
inside a function begins at the end of the ConstSpec or VarSpec
|
||||
and ends at the end of the innermost containing block.</li>
|
||||
|
||||
<li>The scope of a type identifier declared inside a function
|
||||
begins immediately after the identifier in the TypeSpec
|
||||
and ends at the end of the innermost containing block.</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
An identifier declared in a block may be redeclared in an inner block.
|
||||
While the identifier of the inner declaration is in scope, it denotes
|
||||
the entity declared by the inner declaration.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The package clause (§Package clause) is not a declaration; the package name
|
||||
does not appear in any scope. Its purpose is to identify the files belonging
|
||||
to the same package (§Packages) and to specify the default name for import
|
||||
declarations.
|
||||
</p>
|
||||
|
||||
|
||||
<h3>Label scopes</h3>
|
||||
|
||||
<p>
|
||||
Labels are declared by labeled statements (§Labeled statements) and are
|
||||
used in the <code>break</code>, <code>continue</code>, and <code>goto</code>
|
||||
statements (§Break statements, §Continue statements, §Goto statements).
|
||||
In contrast to other identifiers, labels are not block scoped and do
|
||||
not conflict with identifiers that are not labels. The scope of a label
|
||||
is the body of the function in which it is declared and excludes
|
||||
the body of any nested function.
|
||||
</p>
|
||||
|
||||
|
||||
<h3>Predeclared identifiers</h3>
|
||||
|
||||
<p>
|
||||
The following identifiers are implicitly declared in the outermost scope:
|
||||
The following identifiers are implicitly declared in the universe block:
|
||||
</p>
|
||||
<pre class="grammar">
|
||||
Basic types:
|
||||
|
@ -1593,7 +1636,8 @@ A function declaration binds an identifier to a function (§Function types).
|
|||
</p>
|
||||
|
||||
<pre class="ebnf">
|
||||
FunctionDecl = "func" identifier Signature [ Block ] .
|
||||
FunctionDecl = "func" identifier Signature [ Body ] .
|
||||
Body = Block.
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
|
@ -1612,10 +1656,6 @@ func min(x int, y int) int {
|
|||
func flushICache(begin, end uintptr) // implemented externally
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Implementation restriction: Functions can only be declared at the package level.
|
||||
</p>
|
||||
|
||||
<h3>Method declarations</h3>
|
||||
|
||||
<p>
|
||||
|
@ -1623,7 +1663,7 @@ A method declaration binds an identifier to a method,
|
|||
which is a function with a <i>receiver</i>.
|
||||
</p>
|
||||
<pre class="ebnf">
|
||||
MethodDecl = "func" Receiver identifier Signature [ Block ] .
|
||||
MethodDecl = "func" Receiver identifier Signature [ Body ] .
|
||||
Receiver = "(" [ identifier ] [ "*" ] TypeName ")" .
|
||||
</pre>
|
||||
|
||||
|
@ -1664,10 +1704,6 @@ its identifier may be omitted in the declaration. The same applies in
|
|||
general to parameters of functions and methods.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Implementation restriction: They can only be declared at package level.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The type of a method is the type of a function with the receiver as first
|
||||
argument. For instance, the method <code>Scale</code> has type
|
||||
|
@ -1918,8 +1954,7 @@ It consists of a specification of the function type and a function body.
|
|||
</p>
|
||||
|
||||
<pre class="ebnf">
|
||||
FunctionLit = FunctionType Block .
|
||||
Block = "{" StatementList "}" .
|
||||
FunctionLit = FunctionType Body .
|
||||
</pre>
|
||||
|
||||
<pre>
|
||||
|
@ -3218,10 +3253,7 @@ indicate that control should flow from the end of this clause to
|
|||
the first statement of the next clause.
|
||||
Otherwise control flows to the end of the "switch" statement.
|
||||
</p>
|
||||
<p>
|
||||
Each case clause acts as a block for scoping purposes
|
||||
(§Declarations and scope rules).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A "switch" statement may include a simple statement before the
|
||||
expression.
|
||||
|
@ -3505,10 +3537,6 @@ SendExpr = Expression "<-" Expression .
|
|||
RecvExpr = [ Expression ( "=" | ":=" ) ] "<-" Expression .
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Each communication clause acts as a block for the purpose of scoping
|
||||
(§Declarations and scope rules).
|
||||
</p>
|
||||
<p>
|
||||
For all the send and receive expressions in the "select"
|
||||
statement, the channel expression is evaluated. Any expressions
|
||||
|
@ -3973,13 +4001,11 @@ Each source file consists of a package clause defining the package
|
|||
to which it belongs, followed by a possibly empty set of import
|
||||
declarations that declare packages whose contents it wishes to use,
|
||||
followed by a possibly empty set of declarations of functions,
|
||||
types, variables, and constants. The source text following the
|
||||
package clause acts as a block for scoping (§Declarations and scope
|
||||
rules).
|
||||
types, variables, and constants.
|
||||
</p>
|
||||
|
||||
<pre class="ebnf">
|
||||
SourceFile = PackageClause { ImportDecl [ ";" ] } { Declaration [ ";" ] } .
|
||||
SourceFile = PackageClause { ImportDecl [ ";" ] } { TopLevelDecl [ ";" ] } .
|
||||
</pre>
|
||||
|
||||
<h3>Package clause</h3>
|
||||
|
@ -4002,7 +4028,7 @@ A set of files sharing the same PackageName form the implementation of a package
|
|||
An implementation may require that all source files for a package inhabit the same directory.
|
||||
</p>
|
||||
|
||||
<h3>Import</h3>
|
||||
<h3>Import declarations</h3>
|
||||
|
||||
<p>
|
||||
A source file gains access to exported identifiers (§Exported
|
||||
|
|
Loading…
Reference in a new issue