| <!--{ | |
| "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 := 1.0 | |
| for i := 0; i < 1000; i++ { | |
| z -= (z*z - x) / (2 * z) | |
| } | |
| 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 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_paths">go help importpath</a></code>. | |
| </p> | |
| <h2 id="next">What's next</h2> | |
| <p> | |
| Subscribe to the | |
| <a href="http://groups.google.com/group/golang-announce">golang-announce</a> | |
| mailing list to be notified when a new stable version of Go is released. | |
| </p> | |
| <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> | |
| <h2 id="help">Getting help</h2> | |
| <p> | |
| For real-time help, ask the helpful gophers in <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> | |
| Report bugs using the | |
| <a href="http://code.google.com/p/go/issues/list">Go issue tracker</a>. | |
| </p> |