<!--{ "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 tool</a>, the standard way to fetch, build, and install Go packages and commands. </p> <p> The <code>go</code> tool requires you to organize your code in a specific way. Please read this document carefully. It explains the simplest way to get up and running with your Go installation. </p> <p> A similar explanation is available as a <a href="http://www.youtube.com/watch?v=XCsL89YtqCs">screencast</a>. </p> <h2 id="Organization">Code organization</h2> <h3 id="Workspaces">Workspaces</h3> <p> The <code>go</code> tool is designed to work with open source code maintained in public repositories. Although you don't need to publish your code, the model for how the environment is set up works the same whether you do or not. </p> <p> Go code must be kept inside a <i>workspace</i>. A workspace is a directory hierarchy with three directories at its root: </p> <ul> <li><code>src</code> contains Go source files organized into packages (one package per directory), <li><code>pkg</code> contains package objects, and <li><code>bin</code> contains executable commands. </ul> <p> The <code>go</code> tool builds source packages and installs the resulting binaries to the <code>pkg</code> and <code>bin</code> directories. </p> <p> The <code>src</code> subdirectory typically contains multiple version control repositories (such as for Git or Mercurial) that track the development of one or more source packages. </p> <p> To give you an idea of how a workspace looks in practice, here's an example: </p> <pre> bin/ streak # command executable todo # command executable pkg/ linux_amd64/ code.google.com/p/goauth2/ oauth.a # package object github.com/nf/todo/ task.a # package object src/ code.google.com/p/goauth2/ .hg/ # mercurial repository metadata oauth/ oauth.go # package source oauth_test.go # test source github.com/nf/ streak/ .git/ # git repository metadata oauth.go # command source streak.go # command source todo/ .git/ # git repository metadata task/ task.go # package source todo.go # command source </pre> <p> This workspace contains three repositories (<code>goauth2</code>, <code>streak</code>, and <code>todo</code>) comprising two commands (<code>streak</code> and <code>todo</code>) and two libraries (<code>oauth</code> and <code>task</code>). </p> <p> Commands and libraries are built from different kinds of source packages. We will discuss the distinction <a href="#PackageNames">later</a>. </p> <h3 id="GOPATH">The <code>GOPATH</code> environment variable</h3> <p> The <code>GOPATH</code> environment variable specifies the location of your workspace. It is likely the only environment variable you'll need to set when developing Go code. </p> <p> To get started, create a workspace directory and set <code>GOPATH</code> accordingly. Your workspace can be located wherever you like, but we'll use <code>$HOME/go</code> in this document. Note that this must <b>not</b> be the same path as your Go installation. </p> <pre> $ <b>mkdir $HOME/go</b> $ <b>export GOPATH=$HOME/go</b> </pre> <p> For convenience, add the workspace's <code>bin</code> subdirectory to your <code>PATH</code>: </p> <pre> $ <b>export PATH=$PATH:$GOPATH/bin</b> </pre> <h3 id="PackagePaths">Package paths</h3> <p> The packages from the standard library are given short paths such as <code>"fmt"</code> and <code>"net/http"</code>. For your own packages, you must choose a base path that is unlikely to collide with future additions to the standard library or other external libraries. </p> <p> If you keep your code in a source repository somewhere, then you should use the root of that source repository as your base path. For instance, if you have a <a href="https://github.com/">GitHub</a> account at <code>github.com/user</code>, that should be your base path. </p> <p> Note that you don't need to publish your code to a remote repository before you can build it. It's just a good habit to organize your code as if you will publish it someday. In practice you can choose any arbitrary path name, as long as it is unique to the standard library and greater Go ecosystem. </p> <p> We'll use <code>github.com/user</code> as our base path. Create a directory inside your workspace in which to keep source code: </p> <pre> $ <b>mkdir -p $GOPATH/src/github.com/user</b> </pre> <h3 id="Command">Your first program</h3> <p> To compile and run a simple program, first choose a package path (we'll use <code>github.com/user/hello</code>) and create a corresponding package directory inside your workspace: </p> <pre> $ <b>mkdir $GOPATH/src/github.com/user/hello</b> </pre> <p> Next, create a file named <code>hello.go</code> inside that directory, containing the following Go code. </p> <pre> package main import "fmt" func main() { fmt.Printf("Hello, world.\n") } </pre> <p> Now you can build and install that program with the <code>go</code> tool: </p> <pre> $ <b>go install github.com/user/hello</b> </pre> <p> Note that you can run this command from anywhere on your system. The <code>go</code> tool finds the source code by looking for the <code>github.com/user/hello</code> package inside the workspace specified by <code>GOPATH</code>. </p> <p> You can also omit the package path if you run <code>go install</code> from the package directory: </p> <pre> $ <b>cd $GOPATH/src/github.com/user/hello</b> $ <b>go install</b> </pre> <p> This command builds the <code>hello</code> command, producing an executable binary. It then installs that binary to the workspace's <code>bin</code> directory as <code>hello</code> (or, under Windows, <code>hello.exe</code>). In our example, that will be <code>$GOPATH/bin/hello</code>, which is <code>$HOME/go/bin/hello</code>. </p> <p> The <code>go</code> tool will only print output when an error occurs, so if these commands produce no output they have executed successfully. </p> <p> You can now run the program by typing its full path at the command line: </p> <pre> $ <b>$GOPATH/bin/hello</b> Hello, world. </pre> <p> Or, as you have added <code>$GOPATH/bin</code> to your <code>PATH</code>, just type the binary name: </p> <pre> $ <b>hello</b> Hello, world. </pre> <p> If you're using a source control system, now would be a good time to initialize a repository, add the files, and commit your first change. Again, this step is optional: you do not need to use source control to write Go code. </p> <pre> $ <b>cd $GOPATH/src/github.com/user/hello</b> $ <b>git init</b> Initialized empty Git repository in /home/user/go/src/github.com/user/hello/.git/ $ <b>git add hello.go</b> $ <b>git commit -m "initial commit"</b> [master (root-commit) 0b4507d] initial commit 1 file changed, 1 insertion(+) create mode 100644 hello.go </pre> <p> Pushing the code to a remote repository is left as an exercise for the reader. </p> <h3 id="Library">Your first library</h3> <p> Let's write a library and use it from the <code>hello</code> program. </p> <p> Again, the first step is to choose a package path (we'll use <code>github.com/user/newmath</code>) and create the package directory: </p> <pre> $ <b>mkdir $GOPATH/src/github.com/user/newmath</b> </pre> <p> Next, create a file named <code>sqrt.go</code> in that directory with the following contents. </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 { z := 0.0 for i := 0; i < 1000; i++ { z -= (z*z - x) / (2 * x) } return z } </pre> <p> Now, test that the package compiles with <code>go build</code>: </p> <pre> $ <b>go build github.com/user/newmath</b> </pre> <p> Or, if you are working in the package's source directory, just: </p> <pre> $ <b>go build</b> </pre> <p> This won't produce an output file. To do that, you must use <code>go install</code>, which places the package object inside the <code>pkg</code> directory of the workspace. </p> <p> After confirming that the <code>newmath</code> package builds, modify your original <code>hello.go</code> (which is in <code>$GOPATH/src/github.com/user/hello</code>) to use it: </p> <pre> package main import ( "fmt" <b>"github.com/user/newmath"</b> ) func main() { fmt.Printf("Hello, world. <b>Sqrt(2) = %v\n", newmath.Sqrt(2)</b>) } </pre> <p> Whenever the <code>go</code> tool installs a package or binary, it also installs whatever dependencies it has. So when you install the <code>hello</code> program </p> <pre> $ <b>go install github.com/user/hello</b> </pre> <p> the <code>newmath</code> package will be installed as well, automatically. </p> <p> Running the new version of the program, you should see some numerical output: </p> <pre> $ <b>hello</b> Hello, world. Sqrt(2) = 1.414213562373095 </pre> <p> After the steps above, your workspace should look like this: </p> <pre> bin/ hello # command executable pkg/ linux_amd64/ # this will reflect your OS and architecture github.com/user/ newmath.a # package object src/ github.com/user/ hello/ hello.go # command source newmath/ sqrt.go # package source </pre> <p> Note that <code>go install</code> placed the <code>newmath.a</code> object in a directory inside <code>pkg/linux_amd64</code> that mirrors its source directory. This is so that future invocations of the <code>go</code> tool can find the package object and avoid recompiling the package unnecessarily. The <code>linux_amd64</code> part is there to aid in cross-compilation, and will reflect the operating system and architecture of your system. </p> <p> Go command executables are statically linked; the package objects need not be present to run Go programs. </p> <h3 id="PackageNames">Package names</h3> <p> The first statement in a Go source file must 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>. </p> <p> Executable commands must always use <code>package main</code>. </p> <p> 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> See <a href="/doc/effective_go.html#names">Effective Go</a> to learn more about Go's naming conventions. </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/github.com/user/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> Then run the test with <code>go test</code>: </p> <pre> $ <b>go test github.com/user/newmath</b> ok github.com/user/newmath 0.165s </pre> <p> As always, if you are running the <code>go</code> tool from the package directory, you can omit the package path: </p> <pre> $ <b>go test</b> ok github.com/user/newmath 0.165s </pre> <p> Run <code><a href="/cmd/go/#hdr-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> tool 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> $ <b>go get code.google.com/p/go.example/hello</b> $ <b>$GOPATH/bin/hello</b> 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 github.com/user/ 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 github.com/user/ 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://code.google.com/p/go-wiki/wiki/Projects">Go Wiki</a> and <a href="http://godoc.org/">godoc.org</a> provide lists of external Go projects. </p> <p> For more information on using remote repositories with the <code>go</code> tool, see <code><a href="/cmd/go/#hdr-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>