]> Cypherpunks repositories - gostls13.git/commitdiff
Packages.
authorRob Pike <r@golang.org>
Tue, 3 Mar 2009 00:17:29 +0000 (16:17 -0800)
committerRob Pike <r@golang.org>
Tue, 3 Mar 2009 00:17:29 +0000 (16:17 -0800)
DELTA=170  (73 added, 21 deleted, 76 changed)
OCL=25556
CL=25594

doc/go_spec.html

index d49df958c159cdd653e1593e44ac5d84ba354b8b..3104cc6f2418e1754ff0715945e0c9d44b9a34d9 100644 (file)
@@ -1101,9 +1101,9 @@ to receive. This constraint is called a channel's <i>direction</i>; either
 </p>
 
 <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
-&lt;-chan int     // can only receive ints
+&lt;-chan int     // can only be used to receive ints
 </pre>
 
 <p>
@@ -3065,27 +3065,6 @@ if x := f(); x < y {
 </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>
 
 <p>
@@ -3757,81 +3736,154 @@ m := make(map[string] int, 100);  # map with initial space for 100 elements
 
 <h2>Packages</h2>
 
-A package is a package clause, optionally followed by import declarations,
-followed by a series of declarations.
+<p>
+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">
-Package = PackageClause { ImportDecl [ ";" ] } { Declaration [ ";" ] } .
+SourceFile       = PackageClause { ImportDecl [ ";" ] } { Declaration [ ";" ] } .
 </pre>
 
-The source text following the package clause acts like a block for scoping
-purposes ($Declarations and scope rules).
+<h3>Package clause</h3>
+
 <p>
-Every source file identifies the package to which it belongs.
-The file must begin with a package clause.
+A package clause begins each source file and defines the package
+to which the file belongs.
+</p>
 
 <pre class="grammar">
-PackageClause = "package" PackageName .
+PackageClause    = "package" PackageName .
+</pre>
 
-package Math
+<pre>
+package math
 </pre>
 
+<p>
+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>
 
-A package can gain access to exported identifiers from another package
-through an import declaration:
+<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">
-ImportDecl = "import" ( ImportSpec | "(" [ ImportSpecList ] ")" ) .
-ImportSpecList = ImportSpec { ";" ImportSpec } [ ";" ] .
-ImportSpec = [ "." | PackageName ] PackageFileName .
-PackageFileName = StringLit .
+ImportDecl       = "import" ( ImportSpec | "(" [ ImportSpecList ] ")" ) .
+ImportSpecList   = ImportSpec { ";" ImportSpec } [ ";" ] .
+ImportSpec       = [ "." | PackageName ] PackageFileName .
+PackageFileName  = StringLit .
 </pre>
 
-An import statement makes the exported package-level identifiers of the named
-package file accessible to this package.
 <p>
-In the following discussion, assume we have a package in the
-file "/lib/math", called package "math", which exports the identifiers
-"Sin" and "Cos" denoting the respective trigonometric functions.
+After an import, in the usual case an exported name <i>N</i> from the imported
+package <i>P</i> may be accessed by the qualified identifier
+<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>
-In the general form, with an explicit package name, the import
-statement declares that package name as an identifier whose
-contents are the exported elements of the imported package.
-For instance, after
+In this table, assume we have compiled a package named
+<code>math</code>, which exports function <code>Sin</code>, and
+installed the compiled package in file
+<code>"lib/math"</code>.
+</p>
 
-<pre>
-import M "/lib/math"
+<pre class="grammar">
+Import syntax               Local name of Sin
+
+import M "lib/math"         M.Sin
+import   "lib/math"         math.Sin
+import . "lib/math"         Sin
 </pre>
 
-the contents of the package /lib/math can be accessed by
-"M.Sin", "M.Cos", etc.
+<h3>Multi-file packages</h3>
+
 <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
+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>
-import "/lib/math"
+package math
+
+const twoPi = 6.283185307179586
+
+function Sin(x float) float { return ... }
 </pre>
 
-the contents are accessible by "math.Sin", "math.Cos".
 <p>
-Finally, if instead of a package name the import statement uses
-an explicit period, the contents of the imported package are added
-to the current package. After
-
+and file <code>"math2.go"</code> begins
+</p>
 <pre>
-import . "/lib/math"
+package math
+
+import "lib/math"
 </pre>
 
-the contents are accessible by "Sin" and "Cos".  In this instance, it is
-an error if the import introduces name conflicts.
 <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>
 package main
 
+import "fmt"
+
 // Send the sequence 2, 3, 4, ... to channel 'ch'.
 func generate(ch chan <- int) {
        for i := 2; ; i++ {
@@ -3856,7 +3908,7 @@ func sieve() {
        go generate(ch);  // Start generate() as a subprocess.
        for {
                prime := <-ch;
-               print(prime, "\n");
+               fmt.Print(prime, "\n");
                ch1 := make(chan int);
                go filter(ch, ch1, prime);
                ch = ch1
@@ -3972,7 +4024,7 @@ Program execution begins by initializing the <code>main</code> package and then
 invoking <code>main.main()</code>.
 </p>
 <p>
-When main.main() returns, the program exits.
+When <code>main.main()</code> returns, the program exits.
 </p>
 
 <hr/>