diff --git a/doc/code.html b/doc/code.html index 625a98c1f1..ff3d7dcf00 100644 --- a/doc/code.html +++ b/doc/code.html @@ -5,129 +5,152 @@
-This document explains how to write a new package -and how to test code. -It assumes you have installed Go using the -installation instructions. -
- --Before embarking on a change to an existing -package or the creation of a new package, -be sure to send mail to the -mailing list -to let people know what you are thinking of doing. -Doing so helps avoid duplication of effort and -enables discussions about design before any code -has been written. -
- -
-For real-time help, there may be users or developers on
-#go-nuts on the Freenode IRC server.
-
-The official mailing list for discussion of the Go language is -Go Nuts. -
- --Bugs can be reported using the Go issue tracker. -
- --For those who wish to keep up with development, -there is another mailing list, golang-checkins, -that receives a message summarizing each checkin to the Go repository. +This document demonstrates the development of a simple Go package and +introduces the go command, the standard way to fetch, +build, and install Go packages and commands.
-GOPATH and workspaces
-The standard packages are given short names like fmt and
-net/http for convenience.
-For your own projects, choose a name space that is unlikely
-to collide with future additions to the standard library or other
+One of Go's design goals is to make writing software easier. To that end, the
+go command doesn't use Makefiles or other configuration files to
+guide program construction. Instead, it uses the source code to find
+dependencies and determine build conditions. This means your source code and
+build scripts are always in sync; they are one and the same.
+
+The one thing you must do is set a GOPATH environment variable.
+GOPATH tells the go command (and other related tools)
+where to find and install the Go packages on your system.
+
+GOPATH is a list of paths. It shares the syntax of your system's
+PATH environment variable. A typical GOPATH on
+a Unix system might look like this:
+
+GOPATH=/home/user/ext:/home/user/mygo ++ +
+(On a Windows system use semicolons as the path separator instead of colons.) +
+ +
+Each path in the list (in this case /home/user/ext or
+/home/user/mygo) specifies the location of a workspace.
+A workspace contains Go source files and their associated package objects, and
+command executables. It has a prescribed structure of three subdirectories:
+
src contains Go source files,
+pkg contains compiled package objects, and
+bin contains executable commands.
+
+Subdirectories of the src directory hold independent packages, and
+all source files (.go, .c, .h, and
+.s) in each subdirectory are elements of that subdirectory's
+package.
+
+When building a program that imports the package "widget" the
+go command looks for src/pkg/widget inside the Go root,
+and then—if the package source isn't found there—it searches
+for src/widget inside each workspace in order.
+
+Multiple workspaces can offer some flexibility and convenience, but for now +we'll concern ourselves with only a single workspace. +
+ +
+Let's work through a simple example. First, create a $HOME/mygo
+directory and its src subdirectory:
+
+$ mkdir -p $HOME/mygo/src # create a place to put source code ++ +
+Next, set it as the GOPATH. You should also add the
+bin subdirectory to your PATH environment variable so
+that you can run the commands therein without specifying their full path.
+To do this, add the following lines to $HOME/.profile (or
+equivalent):
+
+export GOPATH=$HOME/mygo +export PATH=$PATH:$HOME/mygo/bin ++ + +
+The standard packages are given short import paths such as "fmt"
+and "net/http" for convenience.
+For your own projects, it is important to choose a base import path that is
+unlikely to collide with future additions to the standard library or other
external libraries.
+The best way to choose an import path is to use the location of your version
+control repository.
For instance, if your source repository is at example.com
or code.google.com/p/example, you should begin your package
paths with that URL, as in "example.com/foo/bar" or
"code.google.com/p/example/foo/bar".
-This way the go tool can automatically
-check out and build the source code from its import path.
+Using this convention, the go command can automatically check out and
+build the source code by its import path alone.
-If you don't intend your code to be installed in this way, you should at
+If you don't intend to install your code in this way, you should at
least use a unique prefix like "widgets/", as in
"widgets/foo/bar". A good rule is to use a prefix such as your
-company or project name since it is unlikely to be used by another group.
-
go tool and GOPATH
-The go tool is the standard means of
-building and installing Go libraries and programs. It is a "zero configuration"
-tool; it determines how to build Go packages from their source code alone.
+company or project name, since it is unlikely to be used by another group.
-To use the go tool effectively you must set the
-GOPATH variable.
-GOPATH specifies a list of paths that contain Go source code
-and package binaries. Source code, package objects, and command binaries are
-located inside the GOPATHs' src, pkg,
-and bin subdirectories respectively.
-
-You should set GOPATH in your shell profile
-($HOME/.bashrc, $HOME/.profile, or equivalent).
-
-This shell session demonstrates setting GOPATH, creating a trivial
-widgets/foo package, and building and installing the package.
+We'll use example/ as our base import path:
-$ export GOPATH=$HOME/gocode -$ mkdir -p $GOPATH/src/widgets/foo -$ cat > $GOPATH/src/widgets/foo/foo.go -package foo -const String = "Go rules!" -^D -$ go install widgets/foo -$ ls $GOPATH/pkg/*/widgets -foo.a +$ mkdir -p $GOPATH/src/example-
(^D means to type Control-D.)
-Type go help gopath on the command line for more information
-about GOPATH.
+The first statement in a Go source file should be
+package name +
-The first statement in a Go source file should be package
-name, where name is the package's default
-name for imports.
+where name is the package's default name for imports.
(All files in a package must use the same name.)
+
Go's convention is that the package name is the last element of the
import path: the package imported as "crypto/rot13"
should be named rot13.
@@ -137,208 +160,344 @@ only that the import paths (their full file names) be unique.
-Go compiles all the source files in a package at once, so one file -can refer to constants, variables, types, and functions in another -file without special arrangement or declarations. -
- --Writing clean, idiomatic Go code is beyond the scope of this document. -Effective Go is an introduction to -that topic. -
- -
-The go tool treats code belonging to
-package main as an executable command, and installs the package
-binary to the GOPATH's bin subdirectory.
-
-Building executable commands is the same as building packages.
-Use "go install":
+Create a new package under example called newmath:
-$ mkdir -p $GOPATH/src/widgets/bar
-$ cat > $GOPATH/src/widgets/bar/bar.go
-package main
-
-import (
- "fmt"
- "widgets/foo"
-)
-
-func main() {
- fmt.Println(foo.String)
-}
-^D
-$ go install widgets/bar
-$ $GOPATH/bin/bar
-Go rules!
+$ cd $GOPATH/src/example
+$ mkdir newmath
-Run go help build and go help install for more
-about building and installing Go binaries.
+Then create a file named $GOPATH/src/example/newmath/sqrt.go
+containing the following Go code:
+// Package newmath is a trivial example package.
+package newmath
+
+// Sqrt returns an approximation to the square root of x.
+func Sqrt(x float64) float64 {
+ // This is a terrible implementation.
+ // Real code should import "math" and use math.Sqrt.
+ z := 0.0
+ for i := 0; i < 1000; i++ {
+ z -= (z*z - x) / (2 * x)
+ }
+ return z
+}
+
+
+
+This package is imported by the path name of the directory it's in, starting
+after the src component:
+
+import "example/newmath" ++ +
+See Effective Go to learn more about +Go's naming conventions. +
+ + +
+The go command comprises several subcommands, the most central being
+install. Running go install importpath builds
+and installs a package and its dependencies.
+
+To "install a package" means to write the package object or executable command
+to the pkg or bin subdirectory of the workspace in
+which the source resides.
+
+To build and install the newmath package, type
+
+$ go install example/newmath ++ +
+This command will produce no output if the package and its dependencies +are built and installed correctly. +
+ +
+As a convenience, the go command will assume the current directory
+if no import path is specified on the command line. This sequence of commands
+has the same affect as the one above:
+
+$ cd $GOPATH/src/example/newmath +$ go install ++ +
+The resulting workspace directory tree (assuimg we're running Linux on a 64-bit +system) looks like this: +
+ ++pkg/ + linux_amd64/ + example/ + newmath.a # package object +src/ + example/ + newmath/ + sqrt.go # package source ++ + +
+The go command treats code belonging to package main as
+an executable command and installs the package binary to the
+GOPATH's bin subdirectory.
+
+Add a command named hello to the source tree.
+First create the example/hello directory:
+
+$ cd $GOPATH/src/example +$ mkdir hello ++ +
+Then create the file $GOPATH/src/example/hello/hello.go
+containing the following Go code.
+
+// Hello is a trivial example of a main package.
+package main
+
+import (
+ "example/newmath"
+ "fmt"
+)
+
+func main() {
+ fmt.Printf("Hello, world. Sqrt(2) = %v\n", newmath.Sqrt(2))
+}
+
+
+
+Next, run go install, which builds and installs the binary to
+$GOPATH/bin:
+
+$ go install example/hello ++ +
+To run the program, invoke it by name as you would any other command: +
+ ++$ $GOPATH/bin/hello +Hello, world. Sqrt(2) = 1.414213562373095 ++ +
+If you added $HOME/mygo/bin to your PATH, you may omit
+the path to the executable:
+
+$ hello +Hello, world. Sqrt(2) = 1.414213562373095 ++ +
+The workspace directory tree now looks like this: +
+ ++bin/ + hello # command executable +pkg/ + linux_amd64/ + example/ + newmath.a # package object +src/ + example/ + hello/ + hello.go # command source + newmath/ + sqrt.go # package source ++ +
+The go command also provides a build command, which is
+like install except it builds all objects in a temporary directory
+and does not install them under pkg or bin.
+When building a command an executable named after the last element of the
+import path is written to the current directory. When building a package,
+go build serves merely to test that the package and its
+dependencies can be built. (The resulting package object is thrown away.)
+
-Go has a lightweight test framework composed of the go tool and
-the testing package.
+Go has a lightweight test framework composed of the go test
+command and the testing package.
+
You write a test by creating a file with a name ending in _test.go
that contains functions named TestXXX with signature
func (t *testing.T).
The test framework runs each such function;
if the function calls a failure function such as t.Error or
t.Fail, the test is considered to have failed.
-Run go help test and see the
-testing package documentation for more detail.
-To run the test, run "go test":
+Add a test to the newmath package by creating the file
+$GOPATH/src/example/newmath/sqrt_test.go containing the following
+Go code.
-$ cat > $GOPATH/src/widgets/foo/foo_test.go
-package foo
+package newmath
import "testing"
-func TestString(t *testing.T) {
- const expect = "Go rules!"
- if String != expect {
- t.Errorf("String == %q, want %q", String, expect)
- }
+func TestSqrt(t *testing.T) {
+ const in, out = 9, 3
+ if x := Sqrt(in); x != out {
+ t.Errorf("Sqrt(%v) = %v, want %v", in, x, out)
+ }
}
-^D
-$ go test widgets/foo
-ok widgets/foo 0.018s
-If your change affects performance, add a Benchmark function
-(run go help testfunc) and run it using go test
--test.bench=.*.
-
-This example package, numbers, consists of the function
-Double, which takes an int and returns that value
-multiplied by 2. It consists of two files.
-
-First, the package implementation, numbers.go:
+Now run the test with go test:
-package numbers
-
-func Double(i int) int {
- return i * 2
-}
+$ go test example/newmath
+ok example/newmath
-Next, the tests, numbers_test.go:
-
-package numbers
-
-import (
- "testing"
-)
-
-type doubleTest struct {
- in, out int
-}
-
-var doubleTests = []doubleTest{
- doubleTest{1, 2},
- doubleTest{2, 4},
- doubleTest{-5, -10},
-}
-
-func TestDouble(t *testing.T) {
- for _, dt := range doubleTests {
- v := Double(dt.in)
- if v != dt.out {
- t.Errorf("Double(%d) = %d, want %d.", dt.in, v, dt.out)
- }
- }
-}
-
-
-
-Running go install will build and install the package to
-the GOPATH's pkg directory
-(it can then be imported by any other Go program).
-
-Running go test will rebuild the package, including the
-numbers_test.go file, and then run the TestDouble
-function. The output "ok" indicates that all tests passed
-successfully. Breaking the implementation by changing the multiplier from
-2 to 3 will allow you to see how failing tests are
-reported.
-
-Run go help test, go help testfunc,
-and go help testflag and see the
+Run go help test and see the
testing package documentation for more detail.
First, a disclaimer: very few Go packages should need to know about the -hardware and operating system they run on. In the vast majority of cases the -language and standard library handle most portability issues. This section is -a guide for experienced systems programmers who have a good reason to write -platform-specific code, such as assembly-language support for fast -trigonometric functions or code that implements a common interface above -different operating systems.
+To compile such code, use the $GOOS and $GOARCH
-environment variables in your
-source file names.
For example, consider the package foo that consists of four
-files:
+An import path can describe how to obtain the package source code using a
+revision control system such as Git or Mercurial. The go command uses
+this property to automatically fetch packages from remote repositories.
+For instance, the examples described in this document are also kept in a
+Mercurial repository hosted at Google Code,
+code.google.com/p/go.example.
+If you include the repository URL in the package's import path,
+go get will fetch, build, and install it automatically:
+
-foo.go -foo_386.go -foo_amd64.go -foo_arm.go +$ go get code.google.com/p/go.example/hello +$ $GOPATH/bin/hello +Hello, world. Sqrt(2) = 1.414213562373095-
describes a package that builds on
-different architectures by parameterizing the file name with
-$GOARCH.
+If the specified package is not present in a workspace, go get
+will place it inside the first workspace specified by GOPATH.
+(If the package does already exist, go get skips the remote
+fetch and behaves the same as go install.)
+
The general code goes in foo.go, while architecture-specific
-code goes in foo_386.go, foo_amd64.go, and
-foo_arm.go.
If you follow these conventional parameterizations, tools such as the go tool will work seamlessly with your
-package:
+After issuing the above go get command, the workspace directory
+tree should now now look like this:
+
-foo_$GOOS.go -foo_$GOARCH.go -foo_$GOOS_$GOARCH.go +bin/ + hello # command executable +pkg/ + linux_amd64/ + code.google.com/p/go.example/ + newmath.a # package object + example/ + newmath.a # package object +src/ + code.google.com/p/go.example/ + hello/ + hello.go # command source + newmath/ + sqrt.go # package source + sqrt_test.go # test source + example/ + hello/ + hello.go # command source + newmath/ + sqrt.go # package source + sqrt_test.go # test source-
The same holds for .s (assembly) and .c files.
+The hello command hosted at Google Code depends on the
+newmath package within the same repository. The imports in
+hello.go file use the same import path convention, so the go
+get command is able to locate and install the dependent package, too.
+
+import "code.google.com/p/go.example/newmath" ++ +
+This convention is the easiest way to make your Go packages available for
+others to use.
+The Go Package Dashboard
+displays a list of packages recently installed with the go command.
+
+For more information on using remote repositories with the go command, see
+go help remote.
+
+See Effective Go for tips on writing +clear, idiomatic Go code. +
+ ++Take A Tour of Go to learn the language +proper. +
+ ++Visit the documentation page for a set of in-depth +articles about the Go language and its libraries and tools. +