mirror of
				https://github.com/golang/go.git
				synced 2025-11-03 18:20:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			503 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			503 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!--{
 | 
						|
	"Title": "How to Write Go Code"
 | 
						|
}-->
 | 
						|
 | 
						|
<h2 id="Introduction">Introduction</h2>
 | 
						|
 | 
						|
<p>
 | 
						|
This document demonstrates the development of a simple Go package and
 | 
						|
introduces the <a href="/cmd/go/">go command</a>, the standard way to fetch,
 | 
						|
build, and install Go packages and commands.
 | 
						|
</p>
 | 
						|
 | 
						|
 | 
						|
<h2 id="GOPATH">Code organization</h2>
 | 
						|
 | 
						|
<h3><code>GOPATH</code> and workspaces</h3>
 | 
						|
 | 
						|
<p>
 | 
						|
One of Go's design goals is to make writing software easier.  To that end, the
 | 
						|
<code>go</code> 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.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
The one thing you must do is set a <code>GOPATH</code> environment variable.
 | 
						|
<code>GOPATH</code> tells the <code>go</code> command (and other related tools)
 | 
						|
where to find and install the Go packages on your system.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
<code>GOPATH</code> is a list of paths. It shares the syntax of your system's
 | 
						|
<code>PATH</code> environment variable. A typical <code>GOPATH</code> on
 | 
						|
a Unix system might look like this:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
GOPATH=/home/user/ext:/home/user/mygo
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
(On a Windows system use semicolons as the path separator instead of colons.)
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
Each path in the list (in this case <code>/home/user/ext</code> or
 | 
						|
<code>/home/user/mygo</code>) specifies the location of a <i>workspace</i>.
 | 
						|
A workspace contains Go source files and their associated package objects, and
 | 
						|
command executables. It has a prescribed structure of three subdirectories:
 | 
						|
</p>
 | 
						|
 | 
						|
<ul>
 | 
						|
<li><code>src</code> contains Go source files,
 | 
						|
<li><code>pkg</code> contains compiled package objects, and
 | 
						|
<li><code>bin</code> contains executable commands.
 | 
						|
</ul>
 | 
						|
 | 
						|
<p>
 | 
						|
Subdirectories of the <code>src</code> directory hold independent packages, and
 | 
						|
all source files (<code>.go</code>, <code>.c</code>, <code>.h</code>, and
 | 
						|
<code>.s</code>) in each subdirectory are elements of that subdirectory's
 | 
						|
package.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
When building a program that imports the package "<code>widget</code>" the
 | 
						|
<code>go</code> command looks for <code>src/pkg/widget</code> inside the Go root,
 | 
						|
and then—if the package source isn't found there—it searches
 | 
						|
for <code>src/widget</code> inside each workspace in order.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
Multiple workspaces can offer some flexibility and convenience, but for now
 | 
						|
we'll concern ourselves with only a single workspace.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
Let's work through a simple example. First, create a <code>$HOME/mygo</code>
 | 
						|
directory and its <code>src</code> subdirectory:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
$ mkdir -p $HOME/mygo/src # create a place to put source code
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
Next, set it as the <code>GOPATH</code>. You should also add the
 | 
						|
<code>bin</code> subdirectory to your <code>PATH</code> environment variable so
 | 
						|
that you can run the commands therein without specifying their full path.
 | 
						|
To do this, add the following lines to <code>$HOME/.profile</code> (or
 | 
						|
equivalent):
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
export GOPATH=$HOME/mygo
 | 
						|
export PATH=$PATH:$HOME/mygo/bin
 | 
						|
</pre>
 | 
						|
 | 
						|
 | 
						|
<h3>Import paths</h3>
 | 
						|
 | 
						|
<p>
 | 
						|
The standard packages are given short import paths such as <code>"fmt"</code>
 | 
						|
and <code>"net/http"</code> 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.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
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 <code>example.com</code> 
 | 
						|
or <code>code.google.com/p/example</code>, you should begin your package
 | 
						|
paths with that URL, as in "<code>example.com/foo/bar</code>" or
 | 
						|
"<code>code.google.com/p/example/foo/bar</code>".
 | 
						|
Using this convention, the <code>go</code> command can automatically check out and
 | 
						|
build the source code by its import path alone.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
If you don't intend to install your code in this way, you should at
 | 
						|
least use a unique prefix like "<code>widgets/</code>", as in
 | 
						|
"<code>widgets/foo/bar</code>". 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.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
We'll use <code>example/</code> as our base import path:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
$ mkdir -p $GOPATH/src/example
 | 
						|
</pre>
 | 
						|
 | 
						|
 | 
						|
<h3>Package names</h3>
 | 
						|
 | 
						|
<p>
 | 
						|
The first statement in a Go source file should be
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
package <i>name</i>
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
where <code><i>name</i></code> is the package's default name for imports.
 | 
						|
(All files in a package must use the same <code><i>name</i></code>.)
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
Go's convention is that the package name is the last element of the
 | 
						|
import path: the package imported as "<code>crypto/rot13</code>"
 | 
						|
should be named <code>rot13</code>.
 | 
						|
There is no requirement that package names be unique
 | 
						|
across all packages linked into a single binary,
 | 
						|
only that the import paths (their full file names) be unique.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
Create a new package under <code>example</code> called <code>newmath</code>:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
$ cd $GOPATH/src/example
 | 
						|
$ mkdir newmath
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
Then create a file named <code>$GOPATH/src/example/newmath/sqrt.go</code>
 | 
						|
containing the following Go code:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
// 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
 | 
						|
}
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
This package is imported by the path name of the directory it's in, starting
 | 
						|
after the <code>src</code> component:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
import "example/newmath"
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
See <a href="/doc/effective_go.html#names">Effective Go</a> to learn more about
 | 
						|
Go's naming conventions.
 | 
						|
</p>
 | 
						|
 | 
						|
 | 
						|
<h2>Building and installing</h2>
 | 
						|
 | 
						|
<p>
 | 
						|
The <code>go</code> command comprises several subcommands, the most central being
 | 
						|
<code>install</code>. Running <code>go install <i>importpath</i></code> builds
 | 
						|
and installs a package and its dependencies.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
To "install a package" means to write the package object or executable command
 | 
						|
to the <code>pkg</code> or <code>bin</code> subdirectory of the workspace in
 | 
						|
which the source resides.
 | 
						|
</p>
 | 
						|
 | 
						|
<h3>Building a package</h3>
 | 
						|
 | 
						|
<p>
 | 
						|
To build and install the <code>newmath</code> package, type
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
$ go install example/newmath
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
This command will produce no output if the package and its dependencies
 | 
						|
are built and installed correctly.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
As a convenience, the <code>go</code> 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:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
$ cd $GOPATH/src/example/newmath
 | 
						|
$ go install
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
The resulting workspace directory tree (assuming we're running Linux on a 64-bit
 | 
						|
system) looks like this:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
pkg/
 | 
						|
    linux_amd64/
 | 
						|
        example/
 | 
						|
            newmath.a  # package object
 | 
						|
src/
 | 
						|
    example/
 | 
						|
        newmath/
 | 
						|
            sqrt.go    # package source
 | 
						|
</pre>
 | 
						|
 | 
						|
 | 
						|
<h3>Building a command</h3>
 | 
						|
 | 
						|
<p>
 | 
						|
The <code>go</code> command treats code belonging to <code>package main</code> as
 | 
						|
an executable command and installs the package binary to the
 | 
						|
<code>GOPATH</code>'s <code>bin</code> subdirectory.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
Add a command named <code>hello</code> to the source tree.
 | 
						|
First create the <code>example/hello</code> directory:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
$ cd $GOPATH/src/example
 | 
						|
$ mkdir hello
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
Then create the file <code>$GOPATH/src/example/hello/hello.go</code>
 | 
						|
containing the following Go code.
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
// 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))
 | 
						|
}
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
Next, run <code>go install</code>, which builds and installs the binary to
 | 
						|
<code>$GOPATH/bin</code>:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
$ go install example/hello
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
To run the program, invoke it by name as you would any other command:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
$ $GOPATH/bin/hello
 | 
						|
Hello, world.  Sqrt(2) = 1.414213562373095
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
If you added <code>$HOME/mygo/bin</code> to your <code>PATH</code>, you may omit
 | 
						|
the path to the executable:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
$ hello
 | 
						|
Hello, world.  Sqrt(2) = 1.414213562373095
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
The workspace directory tree now looks like this:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
bin/
 | 
						|
    hello              # command executable
 | 
						|
pkg/
 | 
						|
    linux_amd64/ 
 | 
						|
        example/
 | 
						|
            newmath.a  # package object
 | 
						|
src/
 | 
						|
    example/
 | 
						|
        hello/
 | 
						|
            hello.go   # command source
 | 
						|
        newmath/
 | 
						|
            sqrt.go    # package source
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
The <code>go</code> command also provides a <code>build</code> command, which is
 | 
						|
like <code>install</code> except it builds all objects in a temporary directory
 | 
						|
and does not install them under <code>pkg</code> or <code>bin</code>.
 | 
						|
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, 
 | 
						|
<code>go build</code> serves merely to test that the package and its
 | 
						|
dependencies can be built. (The resulting package object is thrown away.)
 | 
						|
</p>
 | 
						|
 | 
						|
 | 
						|
<h2 id="Testing">Testing</h2>
 | 
						|
 | 
						|
<p>
 | 
						|
Go has a lightweight test framework composed of the <code>go test</code>
 | 
						|
command and the <code>testing</code> package.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
You write a test by creating a file with a name ending in <code>_test.go</code>
 | 
						|
that contains functions named <code>TestXXX</code> with signature
 | 
						|
<code>func (t *testing.T)</code>.
 | 
						|
The test framework runs each such function;
 | 
						|
if the function calls a failure function such as <code>t.Error</code> or
 | 
						|
<code>t.Fail</code>, the test is considered to have failed.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
Add a test to the <code>newmath</code> package by creating the file
 | 
						|
<code>$GOPATH/src/example/newmath/sqrt_test.go</code> containing the following
 | 
						|
Go code.
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
package newmath
 | 
						|
 | 
						|
import "testing"
 | 
						|
 | 
						|
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)
 | 
						|
        }
 | 
						|
}
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
Now run the test with <code>go test</code>:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
$ go test example/newmath
 | 
						|
ok  	example/newmath
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
Run <code><a href="/cmd/go/#Test_packages">go help test</a></code> and see the
 | 
						|
<a href="/pkg/testing/">testing package documentation</a> for more detail.
 | 
						|
</p>
 | 
						|
 | 
						|
 | 
						|
<h2 id="remote">Remote packages</h2>
 | 
						|
 | 
						|
<p>
 | 
						|
An import path can describe how to obtain the package source code using a
 | 
						|
revision control system such as Git or Mercurial. The <code>go</code> 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><a href="http://code.google.com/p/go.example">code.google.com/p/go.example</a></code>.
 | 
						|
If you include the repository URL in the package's import path,
 | 
						|
<code>go get</code> will fetch, build, and install it automatically:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
$ go get code.google.com/p/go.example/hello
 | 
						|
$ $GOPATH/bin/hello
 | 
						|
Hello, world.  Sqrt(2) = 1.414213562373095
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
If the specified package is not present in a workspace, <code>go get</code>
 | 
						|
will place it inside the first workspace specified by <code>GOPATH</code>.
 | 
						|
(If the package does already exist, <code>go get</code> skips the remote
 | 
						|
fetch and behaves the same as <code>go install</code>.)
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
After issuing the above <code>go get</code> command, the workspace directory
 | 
						|
tree should now now look like this:
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
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
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
The <code>hello</code> command hosted at Google Code depends on the
 | 
						|
<code>newmath</code> package within the same repository. The imports in
 | 
						|
<code>hello.go</code> file use the same import path convention, so the <code>go
 | 
						|
get</code> command is able to locate and install the dependent package, too.
 | 
						|
</p>
 | 
						|
 | 
						|
<pre>
 | 
						|
import "code.google.com/p/go.example/newmath"
 | 
						|
</pre>
 | 
						|
 | 
						|
<p>
 | 
						|
This convention is the easiest way to make your Go packages available for
 | 
						|
others to use.
 | 
						|
The <a href="http://godashboard.appspot.com/package">Go Package Dashboard</a>
 | 
						|
displays a list of packages recently installed with the <code>go</code> command.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
For more information on using remote repositories with the <code>go</code> command, see
 | 
						|
<code><a href="/cmd/go/#Remote_import_path_syntax">go help remote</a></code>.
 | 
						|
</p>
 | 
						|
 | 
						|
 | 
						|
<h2 id="more">Further reading</h2>
 | 
						|
 | 
						|
<p>
 | 
						|
See <a href="/doc/effective_go.html">Effective Go</a> for tips on writing
 | 
						|
clear, idiomatic Go code.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
Take <a href="http://tour.golang.org/">A Tour of Go</a> to learn the language
 | 
						|
proper.
 | 
						|
</p>
 | 
						|
 | 
						|
<p>
 | 
						|
Visit the <a href="/doc/#articles">documentation page</a> for a set of in-depth
 | 
						|
articles about the Go language and its libraries and tools.
 | 
						|
</p>
 |