| <!--{ |
| "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 effect 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> (or <code>$GOBIN</code>, if set; to simplify |
| presentation, this document assumes <code>GOBIN</code> is unset): |
| </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 = 4, 2 |
| 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 0.165s |
| </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">Go Project Dashboard</a> |
| is a list of external Go projects including programs and libraries. |
| </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> |