| <!--{ |
| "Title": "How to Write Go Code" |
| }--> |
| |
| <h2 id="Introduction">Introduction</h2> |
| |
| <p> |
| This document explains how to write a new package |
| and how to test code. |
| It assumes you have installed Go using the |
| <a href="install.html">installation instructions</a>. |
| </p> |
| |
| <p> |
| Before embarking on a change to an existing |
| package or the creation of a new package, |
| be sure to send mail to the |
| <a href="http://groups.google.com/group/golang-nuts">mailing list</a> |
| 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. |
| </p> |
| |
| <h2 id="Community_resources">Community resources</h2> |
| |
| <p> |
| For real-time help, there may be users or developers on |
| <code>#go-nuts</code> on the <a href="http://freenode.net/">Freenode</a> IRC server. |
| </p> |
| |
| <p> |
| The official mailing list for discussion of the Go language is |
| <a href="http://groups.google.com/group/golang-nuts">Go Nuts</a>. |
| </p> |
| |
| <p> |
| Bugs can be reported using the <a href="http://code.google.com/p/go/issues/list">Go issue tracker</a>. |
| </p> |
| |
| <p> |
| For those who wish to keep up with development, |
| there is another mailing list, <a href="http://groups.google.com/group/golang-checkins">golang-checkins</a>, |
| that receives a message summarizing each checkin to the Go repository. |
| </p> |
| |
| |
| <h2 id="New_package">Creating a new package</h2> |
| |
| <h3>Choosing an import path</h3> |
| |
| <p> |
| The standard packages are given short names like <code>fmt</code> and |
| <code>net/http</code> for convenience. |
| For your own projects, choose a name space that is unlikely |
| to collide with future additions to the standard library or other |
| external libraries. |
| </p> |
| |
| <p> |
| 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>". |
| This way the <a href="/cmd/go/"><code>go</code> tool</a> can automatically |
| check out and build the source code from its import path. |
| </p> |
| |
| <p> |
| If you don't intend your code to be installed 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> |
| |
| |
| <h3>The <code>go</code> tool and <code>GOPATH</code></h3> |
| |
| <p> |
| The <a href="/cmd/go/"><code>go</code> tool</a> 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. |
| </p> |
| |
| <p> |
| To use the <code>go</code> tool effectively you must set the |
| <code>GOPATH</code> variable. |
| <code>GOPATH</code> specifies a list of paths that contain Go source code |
| and package binaries. Source code, package objects, and command binaries are |
| located inside the <code>GOPATH</code>s' <code>src</code>, <code>pkg</code>, |
| and <code>bin</code> subdirectories respectively. |
| </p> |
| |
| <p> |
| You should set <code>GOPATH</code> in your shell profile |
| (<code>$HOME/.bashrc</code>, <code>$HOME/.profile</code>, or equivalent). |
| </p> |
| |
| <p> |
| This shell session demonstrates setting <code>GOPATH</code>, creating a trivial |
| <code>widgets/foo</code> package, and building and installing the package. |
| </p> |
| |
| <pre> |
| $ 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/*/example |
| foo.a |
| </pre> |
| |
| <p>(<code>^D</code> means to type Control-D.)</p> |
| |
| <p> |
| Type <code>go help gopath</code> on the command line for more information |
| about <code>GOPATH</code>. |
| </p> |
| |
| |
| <h3>Go source files</h3> |
| |
| <p> |
| The first statement in a Go source file should be <code>package |
| <i>name</i></code>, 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>.) |
| 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> |
| 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. |
| </p> |
| |
| <p> |
| Writing clean, idiomatic Go code is beyond the scope of this document. |
| <a href="effective_go.html">Effective Go</a> is an introduction to |
| that topic. |
| </p> |
| |
| <h2 id="Building_programs">Building programs</h2> |
| |
| <p> |
| The <a href="/cmd/go/"><code>go</code> tool</a> 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> |
| Building executable commands is the same as building packages. |
| Use "<code>go install</code>": |
| </p> |
| |
| <pre> |
| $ 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! |
| </pre> |
| |
| <p> |
| Run <code>go help build</code> and <code>go help install</code> for more |
| about building and installing Go binaries. |
| </p> |
| |
| <h2 id="Testing">Testing</h2> |
| |
| <p> |
| Go has a lightweight test framework composed of the <code>go</code> tool and |
| the <code>testing</code> package. |
| 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. |
| Run <code>go help test</code> and see the |
| <a href="/pkg/testing/">testing package documentation</a> for more detail. |
| </p> |
| |
| <p> |
| To run the test, run "<code>go test</code>": |
| </p> |
| |
| <pre> |
| $ cat > $GOPATH/src/widgets/foo/foo_test.go |
| package foo |
| |
| import "testing" |
| |
| func TestString(t *testing.T) { |
| const expect = "Go rules!" |
| if String != expect { |
| t.Errorf("String == %q, want %q", String, expect) |
| } |
| } |
| ^D |
| $ go test widgets/foo |
| ok widgets/foo |
| </pre> |
| |
| <p> |
| If your change affects performance, add a <code>Benchmark</code> function |
| (run <code>go help testfunc</code>) and run it using <code>go test |
| -test.bench=.*</code>. |
| </p> |
| |
| <h2 id="pkg_example">An example package with tests</h2> |
| |
| <p> |
| This example package, <code>numbers</code>, consists of the function |
| <code>Double</code>, which takes an <code>int</code> and returns that value |
| multiplied by 2. It consists of two files. |
| </p> |
| |
| <p> |
| First, the package implementation, <code>numbers.go</code>: |
| </p> |
| |
| <pre> |
| package numbers |
| |
| func Double(i int) int { |
| return i * 2 |
| } |
| </pre> |
| |
| <p> |
| Next, the tests, <code>numbers_test.go</code>: |
| </p> |
| |
| <pre> |
| 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) |
| } |
| } |
| } |
| </pre> |
| |
| <p> |
| Running <code>go install</code> will build and install the package to |
| the <code>GOPATH</code>'s <code>pkg</code> directory |
| (it can then be imported by any other Go program). |
| </p> |
| |
| <p> |
| Running <code>go test</code> will rebuild the package, including the |
| <code>numbers_test.go</code> file, and then run the <code>TestDouble</code> |
| function. The output "<code>ok</code>" indicates that all tests passed |
| successfully. Breaking the implementation by changing the multiplier from |
| <code>2</code> to <code>3</code> will allow you to see how failing tests are |
| reported. |
| </p> |
| |
| <p> |
| Run <code>go help test</code>, <code>go help testfunc</code>, |
| and <code>go help testflag</code> and see the |
| <a href="/pkg/testing/">testing package documentation</a> for more detail. |
| </p> |
| |
| <h2 id="arch_os_specific">Architecture- and operating system-specific code</h2> |
| |
| <p>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.</p> |
| |
| <p>To compile such code, use the <code>$GOOS</code> and <code>$GOARCH</code> |
| <a href="/doc/install.html#environment">environment variables</a> in your |
| source file names.</p> |
| |
| <p>For example, consider the package <code>foo</code> that consists of four |
| files:</p> |
| |
| <pre> |
| foo.go |
| foo_386.go |
| foo_amd64.go |
| foo_arm.go |
| </pre> |
| |
| describes a package that builds on |
| different operating systems by parameterizing the file name with |
| <code>$GOOS</code>.</p> |
| |
| <p>The general code goes in <code>foo.go</code>, while architecture-specific |
| code goes in <code>foo_386.go</code>, <code>foo_amd64.go</code>, and |
| <code>foo_arm.go</code>.</p> |
| |
| <p>If you follow these conventional parameterizations, tools such as the <a |
| href="/cmd/go/"><code>go</code> tool</a> will work seamlessly with your |
| package:</p> |
| |
| <pre> |
| foo_$GOOS.go |
| foo_$GOARCH.go |
| foo_$GOOS_$GOARCH.go |
| </pre> |
| |
| <p>The same holds for <code>.s</code> (assembly) and <code>.c</code> files.</p> |