1
0
mirror of https://github.com/golang/go synced 2024-11-25 13:07:57 -07:00

Packages.

DELTA=170  (73 added, 21 deleted, 76 changed)
OCL=25556
CL=25594
This commit is contained in:
Rob Pike 2009-03-02 16:17:29 -08:00
parent e9b40580ba
commit 4659685b8f

View File

@ -1101,9 +1101,9 @@ to receive. This constraint is called a channel's <i>direction</i>; either
</p> </p>
<pre> <pre>
chan T // can send and receive values of type T chan T // can be used to send and receive values of type T
chan &lt;- float // can only be used to send floats chan &lt;- float // can only be used to send floats
&lt;-chan int // can only receive ints &lt;-chan int // can only be used to receive ints
</pre> </pre>
<p> <p>
@ -3065,27 +3065,6 @@ if x := f(); x < y {
</pre> </pre>
<!--
TODO: gri thinks that Statement needs to be changed as follows:
IfStat =
"if" [ [ SimpleStat ] ";" ] [ Expression ] Block
[ "else" ( IfStat | Block ) ] .
To facilitate the "if else if" code pattern, if the "else" branch is
simply another "if" statement, that "if" statement may be written
without the surrounding Block:
if x > 0 {
return 0;
} else if x > 10 {
return 1;
} else {
return 2;
}
-->
<h3>Switch statements</h3> <h3>Switch statements</h3>
<p> <p>
@ -3757,28 +3736,61 @@ m := make(map[string] int, 100); # map with initial space for 100 elements
<h2>Packages</h2> <h2>Packages</h2>
A package is a package clause, optionally followed by import declarations, <p>
followed by a series of declarations. Go programs are constructed by linking together <i>packages</i>.
A package is in turn constructed from one or more source files that
together provide an interface to a set of types, constants, functions,
and variables. Those elements may be <i>imported</i> and used in
another package.
</p>
<h3>Source file organization</h3>
<p>
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).
</p>
<pre class="grammar"> <pre class="grammar">
Package = PackageClause { ImportDecl [ ";" ] } { Declaration [ ";" ] } . SourceFile = PackageClause { ImportDecl [ ";" ] } { Declaration [ ";" ] } .
</pre> </pre>
The source text following the package clause acts like a block for scoping <h3>Package clause</h3>
purposes ($Declarations and scope rules).
<p> <p>
Every source file identifies the package to which it belongs. A package clause begins each source file and defines the package
The file must begin with a package clause. to which the file belongs.
</p>
<pre class="grammar"> <pre class="grammar">
PackageClause = "package" PackageName . PackageClause = "package" PackageName .
package Math
</pre> </pre>
<pre>
package math
</pre>
A package can gain access to exported identifiers from another package <p>
through an import declaration: 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>
<p>
A source file gains access to exported identifiers (§Exported
identifiers) from another package through an import declaration.
In the general form, an import declaration provides an identifier
that code in the source file may use to access the imported package's
contents and a file name referring to the (compiled) implementation of
the package. The file name may be relative to a repository of
installed packages.
</p>
<pre class="grammar"> <pre class="grammar">
ImportDecl = "import" ( ImportSpec | "(" [ ImportSpecList ] ")" ) . ImportDecl = "import" ( ImportSpec | "(" [ ImportSpecList ] ")" ) .
@ -3787,51 +3799,91 @@ ImportSpec = [ "." | PackageName ] PackageFileName .
PackageFileName = StringLit . PackageFileName = StringLit .
</pre> </pre>
An import statement makes the exported package-level identifiers of the named
package file accessible to this package.
<p> <p>
In the following discussion, assume we have a package in the After an import, in the usual case an exported name <i>N</i> from the imported
file "/lib/math", called package "math", which exports the identifiers package <i>P</i> may be accessed by the qualified identifier
"Sin" and "Cos" denoting the respective trigonometric functions. <i>P</i><code>.</code><i>N</i> (§Qualified identifiers). The actual
name <i>P</i> depends on the form of the import declaration. If
an explicit package name <code>p1</code> is provided, the qualified
identifer will have the form <code>p1.</code><i>N</i>. If no name
is provided in the import declaration, <i>P</i> will be the package
name declared within the source files of the imported package.
Finally, if the import declaration uses an explicit period
(<code>.</code>) for the package name, <i>N</i> will appear
in the package-level scope of the current file and the qualified name is
unnecessary and erroneous. In this form, it is an error if the import introduces
a name conflict.
</p>
<p> <p>
In the general form, with an explicit package name, the import In this table, assume we have compiled a package named
statement declares that package name as an identifier whose <code>math</code>, which exports function <code>Sin</code>, and
contents are the exported elements of the imported package. installed the compiled package in file
For instance, after <code>"lib/math"</code>.
</p>
<pre> <pre class="grammar">
import M "/lib/math" Import syntax Local name of Sin
import M "lib/math" M.Sin
import "lib/math" math.Sin
import . "lib/math" Sin
</pre> </pre>
the contents of the package /lib/math can be accessed by <h3>Multi-file packages</h3>
"M.Sin", "M.Cos", etc.
<p>
In its simplest form, with no package name, the import statement
implicitly uses the imported package name itself as the local
package name. After
<p>
If a package is constructed from multiple source files, all names
at package-level scope, not just exported names, are visible to all the
files in the package. An import declaration is still necessary to
declare intention to use the names,
but the imported names do not need a qualified identifer to be
accessed.
</p>
<p>
The compilation of a multi-file package may require
that the files be compiled and installed in an order that satisfies
the resolution of names imported within the package.
</p>
<p>
If source file <code>math1.go</code> contains
</p>
<pre> <pre>
import "/lib/math" package math
const twoPi = 6.283185307179586
function Sin(x float) float { return ... }
</pre> </pre>
the contents are accessible by "math.Sin", "math.Cos".
<p> <p>
Finally, if instead of a package name the import statement uses and file <code>"math2.go"</code> begins
an explicit period, the contents of the imported package are added </p>
to the current package. After
<pre> <pre>
import . "/lib/math" package math
import "lib/math"
</pre> </pre>
the contents are accessible by "Sin" and "Cos". In this instance, it is
an error if the import introduces name conflicts.
<p> <p>
Here is a complete example Go package that implements a concurrent prime sieve: then, provided <code>"math1.go"</code> is compiled first and
installed in <code>"lib/math"</code>, <code>math2.go</code>
may refer directly to <code>Sin</code> and <code>twoPi</code>
without a qualified identifier.
</p>
<h3>An example package</h3>
<p>
Here is a complete Go package that implements a concurrent prime sieve.
</p>
<pre> <pre>
package main 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) { func generate(ch chan <- int) {
for i := 2; ; i++ { for i := 2; ; i++ {
@ -3856,7 +3908,7 @@ func sieve() {
go generate(ch); // Start generate() as a subprocess. go generate(ch); // Start generate() as a subprocess.
for { for {
prime := <-ch; prime := <-ch;
print(prime, "\n"); fmt.Print(prime, "\n");
ch1 := make(chan int); ch1 := make(chan int);
go filter(ch, ch1, prime); go filter(ch, ch1, prime);
ch = ch1 ch = ch1
@ -3972,7 +4024,7 @@ Program execution begins by initializing the <code>main</code> package and then
invoking <code>main.main()</code>. invoking <code>main.main()</code>.
</p> </p>
<p> <p>
When main.main() returns, the program exits. When <code>main.main()</code> returns, the program exits.
</p> </p>
<hr/> <hr/>