blob: fdca404ba47e757381404de88651722861a3cec5 [file] [log] [blame]
Colin Cross7bb052a2015-02-03 12:59:37 -08001<!--{
2 "Title": "How to Write Go Code"
3}-->
4
5<h2 id="Introduction">Introduction</h2>
6
7<p>
8This document demonstrates the development of a simple Go package and
9introduces the <a href="/cmd/go/">go tool</a>, the standard way to fetch,
10build, and install Go packages and commands.
11</p>
12
13<p>
14The <code>go</code> tool requires you to organize your code in a specific
15way. Please read this document carefully.
16It explains the simplest way to get up and running with your Go installation.
17</p>
18
19<p>
20A similar explanation is available as a
21<a href="//www.youtube.com/watch?v=XCsL89YtqCs">screencast</a>.
22</p>
23
24
25<h2 id="Organization">Code organization</h2>
26
Dan Willemsen0c157092016-07-08 13:57:52 -070027<h3 id="Overview">Overview</h3>
28
29<ul>
30 <li>Go programmers typically keep all their Go code in a single <i>workspace</i>.</li>
31 <li>A workspace contains many version control <i>repositories</i>
32 (managed by Git, for example).</li>
33 <li>Each repository contains one or more <i>packages</i>.</li>
34 <li>Each package consists of one or more Go source files in a single directory.</li>
35 <li>The path to a package's directory determines its <i>import path</i>.</li>
36</ul>
37
38<p>
39Note that this differs from other programming environments in which every
40project has a separate workspace and workspaces are closely tied to version
41control repositories.
42</p>
43
Colin Cross7bb052a2015-02-03 12:59:37 -080044<h3 id="Workspaces">Workspaces</h3>
45
46<p>
Colin Cross7bb052a2015-02-03 12:59:37 -080047A workspace is a directory hierarchy with three directories at its root:
48</p>
49
50<ul>
Dan Willemsen0c157092016-07-08 13:57:52 -070051<li><code>src</code> contains Go source files,
Colin Cross7bb052a2015-02-03 12:59:37 -080052<li><code>pkg</code> contains package objects, and
53<li><code>bin</code> contains executable commands.
54</ul>
55
56<p>
57The <code>go</code> tool builds source packages and installs the resulting
58binaries to the <code>pkg</code> and <code>bin</code> directories.
59</p>
60
61<p>
62The <code>src</code> subdirectory typically contains multiple version control
63repositories (such as for Git or Mercurial) that track the development of one
64or more source packages.
65</p>
66
67<p>
68To give you an idea of how a workspace looks in practice, here's an example:
69</p>
70
71<pre>
72bin/
73 hello # command executable
74 outyet # command executable
75pkg/
76 linux_amd64/
77 github.com/golang/example/
78 stringutil.a # package object
79src/
80 <a href="https://github.com/golang/example/">github.com/golang/example/</a>
81 .git/ # Git repository metadata
82 hello/
83 hello.go # command source
84 outyet/
85 main.go # command source
86 main_test.go # test source
87 stringutil/
88 reverse.go # package source
89 reverse_test.go # test source
Dan Willemsen0c157092016-07-08 13:57:52 -070090 <a href="https://golang.org/x/image/">golang.org/x/image/</a>
91 .git/ # Git repository metadata
92 bmp/
93 reader.go # package source
94 writer.go # package source
95 ... (many more repositories and packages omitted) ...
Colin Cross7bb052a2015-02-03 12:59:37 -080096</pre>
97
98<p>
Dan Willemsen0c157092016-07-08 13:57:52 -070099The tree above shows a workspace containing two repositories
100(<code>example</code> and <code>image</code>).
101The <code>example</code> repository contains two commands (<code>hello</code>
102and <code>outyet</code>) and one library (<code>stringutil</code>).
103The <code>image</code> repository contains the <code>bmp</code> package
104and <a href="https://godoc.org/golang.org/x/image">several others</a>.
Colin Cross7bb052a2015-02-03 12:59:37 -0800105</p>
106
107<p>
Dan Willemsen0c157092016-07-08 13:57:52 -0700108A typical workspace contains many source repositories containing many
Colin Cross7bb052a2015-02-03 12:59:37 -0800109packages and commands. Most Go programmers keep <i>all</i> their Go source code
110and dependencies in a single workspace.
111</p>
112
113<p>
114Commands and libraries are built from different kinds of source packages.
115We will discuss the distinction <a href="#PackageNames">later</a>.
116</p>
117
118
119<h3 id="GOPATH">The <code>GOPATH</code> environment variable</h3>
120
121<p>
122The <code>GOPATH</code> environment variable specifies the location of your
123workspace. It is likely the only environment variable you'll need to set
124when developing Go code.
125</p>
126
127<p>
128To get started, create a workspace directory and set <code>GOPATH</code>
129accordingly. Your workspace can be located wherever you like, but we'll use
Dan Willemsen6ff23252015-09-15 13:49:18 -0700130<code>$HOME/work</code> in this document. Note that this must <b>not</b> be the
Colin Cross7bb052a2015-02-03 12:59:37 -0800131same path as your Go installation.
Dan Willemsen6ff23252015-09-15 13:49:18 -0700132(Another common setup is to set <code>GOPATH=$HOME</code>.)
Colin Cross7bb052a2015-02-03 12:59:37 -0800133</p>
134
135<pre>
Dan Willemsen6ff23252015-09-15 13:49:18 -0700136$ <b>mkdir $HOME/work</b>
137$ <b>export GOPATH=$HOME/work</b>
Colin Cross7bb052a2015-02-03 12:59:37 -0800138</pre>
139
140<p>
141For convenience, add the workspace's <code>bin</code> subdirectory
142to your <code>PATH</code>:
143</p>
144
145<pre>
146$ <b>export PATH=$PATH:$GOPATH/bin</b>
147</pre>
148
Dan Willemsen6ff23252015-09-15 13:49:18 -0700149<p>
150To learn more about setting up the <code>GOPATH</code> environment variable,
151please see
152<a href="/cmd/go/#hdr-GOPATH_environment_variable"><code>go help gopath</code></a>
153</p>
Colin Cross7bb052a2015-02-03 12:59:37 -0800154
Dan Willemsen0c157092016-07-08 13:57:52 -0700155<h3 id="ImportPaths">Import paths</h3>
Colin Cross7bb052a2015-02-03 12:59:37 -0800156
157<p>
Dan Willemsen0c157092016-07-08 13:57:52 -0700158An <i>import path</i> is a string that uniquely identifies a package.
159A package's import path corresponds to its location inside a workspace
160or in a remote repository (explained below).
161</p>
162
163<p>
164The packages from the standard library are given short import paths such as
Colin Cross7bb052a2015-02-03 12:59:37 -0800165<code>"fmt"</code> and <code>"net/http"</code>.
166For your own packages, you must choose a base path that is unlikely to
167collide with future additions to the standard library or other external
168libraries.
169</p>
170
171<p>
172If you keep your code in a source repository somewhere, then you should use the
173root of that source repository as your base path.
174For instance, if you have a <a href="https://github.com/">GitHub</a> account at
175<code>github.com/user</code>, that should be your base path.
176</p>
177
178<p>
179Note that you don't need to publish your code to a remote repository before you
180can build it. It's just a good habit to organize your code as if you will
181publish it someday. In practice you can choose any arbitrary path name,
182as long as it is unique to the standard library and greater Go ecosystem.
183</p>
184
185<p>
186We'll use <code>github.com/user</code> as our base path. Create a directory
187inside your workspace in which to keep source code:
188</p>
189
190<pre>
191$ <b>mkdir -p $GOPATH/src/github.com/user</b>
192</pre>
193
194
195<h3 id="Command">Your first program</h3>
196
197<p>
198To compile and run a simple program, first choose a package path (we'll use
199<code>github.com/user/hello</code>) and create a corresponding package directory
200inside your workspace:
201</p>
202
203<pre>
204$ <b>mkdir $GOPATH/src/github.com/user/hello</b>
205</pre>
206
207<p>
208Next, create a file named <code>hello.go</code> inside that directory,
209containing the following Go code.
210</p>
211
212<pre>
213package main
214
215import "fmt"
216
217func main() {
218 fmt.Printf("Hello, world.\n")
219}
220</pre>
221
222<p>
223Now you can build and install that program with the <code>go</code> tool:
224</p>
225
226<pre>
227$ <b>go install github.com/user/hello</b>
228</pre>
229
230<p>
231Note that you can run this command from anywhere on your system. The
232<code>go</code> tool finds the source code by looking for the
233<code>github.com/user/hello</code> package inside the workspace specified by
234<code>GOPATH</code>.
235</p>
236
237<p>
238You can also omit the package path if you run <code>go install</code> from the
239package directory:
240</p>
241
242<pre>
243$ <b>cd $GOPATH/src/github.com/user/hello</b>
244$ <b>go install</b>
245</pre>
246
247<p>
248This command builds the <code>hello</code> command, producing an executable
249binary. It then installs that binary to the workspace's <code>bin</code>
250directory as <code>hello</code> (or, under Windows, <code>hello.exe</code>).
251In our example, that will be <code>$GOPATH/bin/hello</code>, which is
Dan Willemsen6ff23252015-09-15 13:49:18 -0700252<code>$HOME/work/bin/hello</code>.
Colin Cross7bb052a2015-02-03 12:59:37 -0800253</p>
254
255<p>
256The <code>go</code> tool will only print output when an error occurs, so if
257these commands produce no output they have executed successfully.
258</p>
259
260<p>
261You can now run the program by typing its full path at the command line:
262</p>
263
264<pre>
265$ <b>$GOPATH/bin/hello</b>
266Hello, world.
267</pre>
268
269<p>
270Or, as you have added <code>$GOPATH/bin</code> to your <code>PATH</code>,
271just type the binary name:
272</p>
273
274<pre>
275$ <b>hello</b>
276Hello, world.
277</pre>
278
279<p>
280If you're using a source control system, now would be a good time to initialize
281a repository, add the files, and commit your first change. Again, this step is
282optional: you do not need to use source control to write Go code.
283</p>
284
285<pre>
286$ <b>cd $GOPATH/src/github.com/user/hello</b>
287$ <b>git init</b>
Dan Willemsen6ff23252015-09-15 13:49:18 -0700288Initialized empty Git repository in /home/user/work/src/github.com/user/hello/.git/
Colin Cross7bb052a2015-02-03 12:59:37 -0800289$ <b>git add hello.go</b>
290$ <b>git commit -m "initial commit"</b>
291[master (root-commit) 0b4507d] initial commit
292 1 file changed, 1 insertion(+)
293 create mode 100644 hello.go
294</pre>
295
296<p>
297Pushing the code to a remote repository is left as an exercise for the reader.
298</p>
299
300
301<h3 id="Library">Your first library</h3>
302
303<p>
304Let's write a library and use it from the <code>hello</code> program.
305</p>
306
307<p>
308Again, the first step is to choose a package path (we'll use
309<code>github.com/user/stringutil</code>) and create the package directory:
310</p>
311
312<pre>
313$ <b>mkdir $GOPATH/src/github.com/user/stringutil</b>
314</pre>
315
316<p>
317Next, create a file named <code>reverse.go</code> in that directory with the
318following contents.
319</p>
320
321<pre>
322// Package stringutil contains utility functions for working with strings.
323package stringutil
324
325// Reverse returns its argument string reversed rune-wise left to right.
326func Reverse(s string) string {
327 r := []rune(s)
328 for i, j := 0, len(r)-1; i &lt; len(r)/2; i, j = i+1, j-1 {
329 r[i], r[j] = r[j], r[i]
330 }
331 return string(r)
332}
333</pre>
334
335<p>
336Now, test that the package compiles with <code>go build</code>:
337</p>
338
339<pre>
340$ <b>go build github.com/user/stringutil</b>
341</pre>
342
343<p>
344Or, if you are working in the package's source directory, just:
345</p>
346
347<pre>
348$ <b>go build</b>
349</pre>
350
351<p>
352This won't produce an output file. To do that, you must use <code>go
353install</code>, which places the package object inside the <code>pkg</code>
354directory of the workspace.
355</p>
356
357<p>
358After confirming that the <code>stringutil</code> package builds,
359modify your original <code>hello.go</code> (which is in
360<code>$GOPATH/src/github.com/user/hello</code>) to use it:
361</p>
362
363<pre>
364package main
365
366import (
367 "fmt"
368
369 <b>"github.com/user/stringutil"</b>
370)
371
372func main() {
373 fmt.Printf(stringutil.Reverse("!oG ,olleH"))
374}
375</pre>
376
377<p>
378Whenever the <code>go</code> tool installs a package or binary, it also
379installs whatever dependencies it has.
380So when you install the <code>hello</code> program
381</p>
382
383<pre>
384$ <b>go install github.com/user/hello</b>
385</pre>
386
387<p>
388the <code>stringutil</code> package will be installed as well, automatically.
389</p>
390
391<p>
392Running the new version of the program, you should see a new, reversed message:
393</p>
394
395<pre>
396$ <b>hello</b>
397Hello, Go!
398</pre>
399
400<p>
401After the steps above, your workspace should look like this:
402</p>
403
404<pre>
405bin/
406 hello # command executable
407pkg/
408 linux_amd64/ # this will reflect your OS and architecture
409 github.com/user/
410 stringutil.a # package object
411src/
412 github.com/user/
413 hello/
414 hello.go # command source
415 stringutil/
416 reverse.go # package source
417</pre>
418
419<p>
420Note that <code>go install</code> placed the <code>stringutil.a</code> object
421in a directory inside <code>pkg/linux_amd64</code> that mirrors its source
422directory.
423This is so that future invocations of the <code>go</code> tool can find the
424package object and avoid recompiling the package unnecessarily.
425The <code>linux_amd64</code> part is there to aid in cross-compilation,
426and will reflect the operating system and architecture of your system.
427</p>
428
429<p>
430Go command executables are statically linked; the package objects need not
431be present to run Go programs.
432</p>
433
434
435<h3 id="PackageNames">Package names</h3>
436
437<p>
438The first statement in a Go source file must be
439</p>
440
441<pre>
442package <i>name</i>
443</pre>
444
445<p>
446where <code><i>name</i></code> is the package's default name for imports.
447(All files in a package must use the same <code><i>name</i></code>.)
448</p>
449
450<p>
451Go's convention is that the package name is the last element of the
452import path: the package imported as "<code>crypto/rot13</code>"
453should be named <code>rot13</code>.
454</p>
455
456<p>
457Executable commands must always use <code>package main</code>.
458</p>
459
460<p>
461There is no requirement that package names be unique
462across all packages linked into a single binary,
463only that the import paths (their full file names) be unique.
464</p>
465
466<p>
467See <a href="/doc/effective_go.html#names">Effective Go</a> to learn more about
468Go's naming conventions.
469</p>
470
471
472<h2 id="Testing">Testing</h2>
473
474<p>
475Go has a lightweight test framework composed of the <code>go test</code>
476command and the <code>testing</code> package.
477</p>
478
479<p>
480You write a test by creating a file with a name ending in <code>_test.go</code>
481that contains functions named <code>TestXXX</code> with signature
482<code>func (t *testing.T)</code>.
483The test framework runs each such function;
484if the function calls a failure function such as <code>t.Error</code> or
485<code>t.Fail</code>, the test is considered to have failed.
486</p>
487
488<p>
489Add a test to the <code>stringutil</code> package by creating the file
490<code>$GOPATH/src/github.com/user/stringutil/reverse_test.go</code> containing
491the following Go code.
492</p>
493
494<pre>
495package stringutil
496
497import "testing"
498
499func TestReverse(t *testing.T) {
500 cases := []struct {
501 in, want string
502 }{
503 {"Hello, world", "dlrow ,olleH"},
504 {"Hello, 世界", "界世 ,olleH"},
505 {"", ""},
506 }
507 for _, c := range cases {
508 got := Reverse(c.in)
509 if got != c.want {
510 t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
511 }
512 }
513}
514</pre>
515
516<p>
517Then run the test with <code>go test</code>:
518</p>
519
520<pre>
521$ <b>go test github.com/user/stringutil</b>
522ok github.com/user/stringutil 0.165s
523</pre>
524
525<p>
526As always, if you are running the <code>go</code> tool from the package
527directory, you can omit the package path:
528</p>
529
530<pre>
531$ <b>go test</b>
532ok github.com/user/stringutil 0.165s
533</pre>
534
535<p>
536Run <code><a href="/cmd/go/#hdr-Test_packages">go help test</a></code> and see the
537<a href="/pkg/testing/">testing package documentation</a> for more detail.
538</p>
539
540
541<h2 id="remote">Remote packages</h2>
542
543<p>
544An import path can describe how to obtain the package source code using a
545revision control system such as Git or Mercurial. The <code>go</code> tool uses
546this property to automatically fetch packages from remote repositories.
547For instance, the examples described in this document are also kept in a
548Git repository hosted at GitHub
549<code><a href="https://github.com/golang/example">github.com/golang/example</a></code>.
550If you include the repository URL in the package's import path,
551<code>go get</code> will fetch, build, and install it automatically:
552</p>
553
554<pre>
555$ <b>go get github.com/golang/example/hello</b>
556$ <b>$GOPATH/bin/hello</b>
557Hello, Go examples!
558</pre>
559
560<p>
561If the specified package is not present in a workspace, <code>go get</code>
562will place it inside the first workspace specified by <code>GOPATH</code>.
563(If the package does already exist, <code>go get</code> skips the remote
564fetch and behaves the same as <code>go install</code>.)
565</p>
566
567<p>
568After issuing the above <code>go get</code> command, the workspace directory
569tree should now look like this:
570</p>
571
572<pre>
573bin/
574 hello # command executable
575pkg/
576 linux_amd64/
577 github.com/golang/example/
578 stringutil.a # package object
579 github.com/user/
580 stringutil.a # package object
581src/
582 github.com/golang/example/
583 .git/ # Git repository metadata
584 hello/
585 hello.go # command source
586 stringutil/
587 reverse.go # package source
588 reverse_test.go # test source
589 github.com/user/
590 hello/
591 hello.go # command source
592 stringutil/
593 reverse.go # package source
594 reverse_test.go # test source
595</pre>
596
597<p>
598The <code>hello</code> command hosted at GitHub depends on the
599<code>stringutil</code> package within the same repository. The imports in
600<code>hello.go</code> file use the same import path convention, so the
601<code>go get</code> command is able to locate and install the dependent
602package, too.
603</p>
604
605<pre>
606import "github.com/golang/example/stringutil"
607</pre>
608
609<p>
610This convention is the easiest way to make your Go packages available for
611others to use.
612The <a href="//golang.org/wiki/Projects">Go Wiki</a>
613and <a href="//godoc.org/">godoc.org</a>
614provide lists of external Go projects.
615</p>
616
617<p>
618For more information on using remote repositories with the <code>go</code> tool, see
619<code><a href="/cmd/go/#hdr-Remote_import_paths">go help importpath</a></code>.
620</p>
621
622
623<h2 id="next">What's next</h2>
624
625<p>
626Subscribe to the
627<a href="//groups.google.com/group/golang-announce">golang-announce</a>
628mailing list to be notified when a new stable version of Go is released.
629</p>
630
631<p>
632See <a href="/doc/effective_go.html">Effective Go</a> for tips on writing
633clear, idiomatic Go code.
634</p>
635
636<p>
637Take <a href="//tour.golang.org/">A Tour of Go</a> to learn the language
638proper.
639</p>
640
641<p>
642Visit the <a href="/doc/#articles">documentation page</a> for a set of in-depth
643articles about the Go language and its libraries and tools.
644</p>
645
646
647<h2 id="help">Getting help</h2>
648
649<p>
650For real-time help, ask the helpful gophers in <code>#go-nuts</code> on the
651<a href="http://freenode.net/">Freenode</a> IRC server.
652</p>
653
654<p>
655The official mailing list for discussion of the Go language is
656<a href="//groups.google.com/group/golang-nuts">Go Nuts</a>.
657</p>
658
659<p>
660Report bugs using the
661<a href="//golang.org/issue">Go issue tracker</a>.
662</p>