blob: 796431aa1445df252ec3725fd1b36155cd84ec8f [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
Dan Willemsenbbdf6642017-01-13 22:57:23 -0800123workspace. It defaults to a directory named <code>go</code> inside your home directory,
124so <code>$HOME/go</code> on Unix,
125<code>$home/go</code> on Plan 9,
126and <code>%USERPROFILE%\go</code> (usually <code>C:\Users\YourName\go</code>) on Windows.
127If you would like to work in a different location, you will need to set
128<code>GOPATH</code> to the path to that directory.
129(Another common setup is to set <code>GOPATH=$HOME</code>.)
130Note that <code>GOPATH</code> must <b>not</b> be the
131same path as your Go installation.
Colin Cross7bb052a2015-02-03 12:59:37 -0800132</p>
133
134<p>
Dan Willemsenbbdf6642017-01-13 22:57:23 -0800135The command <code>go</code> <code>env</code> <code>GOPATH</code>
136prints the effective current <code>GOPATH</code>;
137it prints the default location if the environment variable is unset.
Colin Cross7bb052a2015-02-03 12:59:37 -0800138</p>
139
Colin Cross7bb052a2015-02-03 12:59:37 -0800140<p>
141For convenience, add the workspace's <code>bin</code> subdirectory
142to your <code>PATH</code>:
143</p>
144
145<pre>
Dan Willemsenbbdf6642017-01-13 22:57:23 -0800146$ <b>export PATH=$PATH:$(go env GOPATH)/bin</b>
Colin Cross7bb052a2015-02-03 12:59:37 -0800147</pre>
148
Dan Willemsen6ff23252015-09-15 13:49:18 -0700149<p>
Dan Willemsenbbdf6642017-01-13 22:57:23 -0800150The scripts in the rest of this document use <code>$GOPATH</code>
151instead of <code>$(go env GOPATH)</code> for brevity.
152To make the scripts run as written
153if you have not set GOPATH,
154you can substitute $HOME/go in those commands
155or else run:
156</p>
157
158<pre>
159$ <b>export GOPATH=$(go env GOPATH)</b>
160</pre>
161
162<p>
163To learn more about the <code>GOPATH</code> environment variable, see
164<a href="/cmd/go/#hdr-GOPATH_environment_variable"><code>'go help gopath'</code></a>.
165</p>
166
167<p>
168To use a custom workspace location,
169<a href="https://golang.org/wiki/SettingGOPATH">set the <code>GOPATH</code> environment variable</a>.
Dan Willemsen6ff23252015-09-15 13:49:18 -0700170</p>
Colin Cross7bb052a2015-02-03 12:59:37 -0800171
Dan Willemsen0c157092016-07-08 13:57:52 -0700172<h3 id="ImportPaths">Import paths</h3>
Colin Cross7bb052a2015-02-03 12:59:37 -0800173
174<p>
Dan Willemsen0c157092016-07-08 13:57:52 -0700175An <i>import path</i> is a string that uniquely identifies a package.
176A package's import path corresponds to its location inside a workspace
177or in a remote repository (explained below).
178</p>
179
180<p>
181The packages from the standard library are given short import paths such as
Colin Cross7bb052a2015-02-03 12:59:37 -0800182<code>"fmt"</code> and <code>"net/http"</code>.
183For your own packages, you must choose a base path that is unlikely to
184collide with future additions to the standard library or other external
185libraries.
186</p>
187
188<p>
189If you keep your code in a source repository somewhere, then you should use the
190root of that source repository as your base path.
191For instance, if you have a <a href="https://github.com/">GitHub</a> account at
192<code>github.com/user</code>, that should be your base path.
193</p>
194
195<p>
196Note that you don't need to publish your code to a remote repository before you
197can build it. It's just a good habit to organize your code as if you will
198publish it someday. In practice you can choose any arbitrary path name,
199as long as it is unique to the standard library and greater Go ecosystem.
200</p>
201
202<p>
203We'll use <code>github.com/user</code> as our base path. Create a directory
204inside your workspace in which to keep source code:
205</p>
206
207<pre>
208$ <b>mkdir -p $GOPATH/src/github.com/user</b>
209</pre>
210
211
212<h3 id="Command">Your first program</h3>
213
214<p>
215To compile and run a simple program, first choose a package path (we'll use
216<code>github.com/user/hello</code>) and create a corresponding package directory
217inside your workspace:
218</p>
219
220<pre>
221$ <b>mkdir $GOPATH/src/github.com/user/hello</b>
222</pre>
223
224<p>
225Next, create a file named <code>hello.go</code> inside that directory,
226containing the following Go code.
227</p>
228
229<pre>
230package main
231
232import "fmt"
233
234func main() {
235 fmt.Printf("Hello, world.\n")
236}
237</pre>
238
239<p>
240Now you can build and install that program with the <code>go</code> tool:
241</p>
242
243<pre>
244$ <b>go install github.com/user/hello</b>
245</pre>
246
247<p>
248Note that you can run this command from anywhere on your system. The
249<code>go</code> tool finds the source code by looking for the
250<code>github.com/user/hello</code> package inside the workspace specified by
251<code>GOPATH</code>.
252</p>
253
254<p>
255You can also omit the package path if you run <code>go install</code> from the
256package directory:
257</p>
258
259<pre>
260$ <b>cd $GOPATH/src/github.com/user/hello</b>
261$ <b>go install</b>
262</pre>
263
264<p>
265This command builds the <code>hello</code> command, producing an executable
266binary. It then installs that binary to the workspace's <code>bin</code>
267directory as <code>hello</code> (or, under Windows, <code>hello.exe</code>).
268In our example, that will be <code>$GOPATH/bin/hello</code>, which is
Dan Willemsen6ff23252015-09-15 13:49:18 -0700269<code>$HOME/work/bin/hello</code>.
Colin Cross7bb052a2015-02-03 12:59:37 -0800270</p>
271
272<p>
273The <code>go</code> tool will only print output when an error occurs, so if
274these commands produce no output they have executed successfully.
275</p>
276
277<p>
278You can now run the program by typing its full path at the command line:
279</p>
280
281<pre>
282$ <b>$GOPATH/bin/hello</b>
283Hello, world.
284</pre>
285
286<p>
287Or, as you have added <code>$GOPATH/bin</code> to your <code>PATH</code>,
288just type the binary name:
289</p>
290
291<pre>
292$ <b>hello</b>
293Hello, world.
294</pre>
295
296<p>
297If you're using a source control system, now would be a good time to initialize
298a repository, add the files, and commit your first change. Again, this step is
299optional: you do not need to use source control to write Go code.
300</p>
301
302<pre>
303$ <b>cd $GOPATH/src/github.com/user/hello</b>
304$ <b>git init</b>
Dan Willemsen6ff23252015-09-15 13:49:18 -0700305Initialized empty Git repository in /home/user/work/src/github.com/user/hello/.git/
Colin Cross7bb052a2015-02-03 12:59:37 -0800306$ <b>git add hello.go</b>
307$ <b>git commit -m "initial commit"</b>
308[master (root-commit) 0b4507d] initial commit
309 1 file changed, 1 insertion(+)
310 create mode 100644 hello.go
311</pre>
312
313<p>
314Pushing the code to a remote repository is left as an exercise for the reader.
315</p>
316
317
318<h3 id="Library">Your first library</h3>
319
320<p>
321Let's write a library and use it from the <code>hello</code> program.
322</p>
323
324<p>
325Again, the first step is to choose a package path (we'll use
326<code>github.com/user/stringutil</code>) and create the package directory:
327</p>
328
329<pre>
330$ <b>mkdir $GOPATH/src/github.com/user/stringutil</b>
331</pre>
332
333<p>
334Next, create a file named <code>reverse.go</code> in that directory with the
335following contents.
336</p>
337
338<pre>
339// Package stringutil contains utility functions for working with strings.
340package stringutil
341
342// Reverse returns its argument string reversed rune-wise left to right.
343func Reverse(s string) string {
344 r := []rune(s)
345 for i, j := 0, len(r)-1; i &lt; len(r)/2; i, j = i+1, j-1 {
346 r[i], r[j] = r[j], r[i]
347 }
348 return string(r)
349}
350</pre>
351
352<p>
353Now, test that the package compiles with <code>go build</code>:
354</p>
355
356<pre>
357$ <b>go build github.com/user/stringutil</b>
358</pre>
359
360<p>
361Or, if you are working in the package's source directory, just:
362</p>
363
364<pre>
365$ <b>go build</b>
366</pre>
367
368<p>
369This won't produce an output file. To do that, you must use <code>go
370install</code>, which places the package object inside the <code>pkg</code>
371directory of the workspace.
372</p>
373
374<p>
375After confirming that the <code>stringutil</code> package builds,
376modify your original <code>hello.go</code> (which is in
377<code>$GOPATH/src/github.com/user/hello</code>) to use it:
378</p>
379
380<pre>
381package main
382
383import (
384 "fmt"
385
386 <b>"github.com/user/stringutil"</b>
387)
388
389func main() {
390 fmt.Printf(stringutil.Reverse("!oG ,olleH"))
391}
392</pre>
393
394<p>
395Whenever the <code>go</code> tool installs a package or binary, it also
396installs whatever dependencies it has.
397So when you install the <code>hello</code> program
398</p>
399
400<pre>
401$ <b>go install github.com/user/hello</b>
402</pre>
403
404<p>
405the <code>stringutil</code> package will be installed as well, automatically.
406</p>
407
408<p>
409Running the new version of the program, you should see a new, reversed message:
410</p>
411
412<pre>
413$ <b>hello</b>
414Hello, Go!
415</pre>
416
417<p>
418After the steps above, your workspace should look like this:
419</p>
420
421<pre>
422bin/
423 hello # command executable
424pkg/
425 linux_amd64/ # this will reflect your OS and architecture
426 github.com/user/
427 stringutil.a # package object
428src/
429 github.com/user/
430 hello/
431 hello.go # command source
432 stringutil/
433 reverse.go # package source
434</pre>
435
436<p>
437Note that <code>go install</code> placed the <code>stringutil.a</code> object
438in a directory inside <code>pkg/linux_amd64</code> that mirrors its source
439directory.
440This is so that future invocations of the <code>go</code> tool can find the
441package object and avoid recompiling the package unnecessarily.
442The <code>linux_amd64</code> part is there to aid in cross-compilation,
443and will reflect the operating system and architecture of your system.
444</p>
445
446<p>
447Go command executables are statically linked; the package objects need not
448be present to run Go programs.
449</p>
450
451
452<h3 id="PackageNames">Package names</h3>
453
454<p>
455The first statement in a Go source file must be
456</p>
457
458<pre>
459package <i>name</i>
460</pre>
461
462<p>
463where <code><i>name</i></code> is the package's default name for imports.
464(All files in a package must use the same <code><i>name</i></code>.)
465</p>
466
467<p>
468Go's convention is that the package name is the last element of the
469import path: the package imported as "<code>crypto/rot13</code>"
470should be named <code>rot13</code>.
471</p>
472
473<p>
474Executable commands must always use <code>package main</code>.
475</p>
476
477<p>
478There is no requirement that package names be unique
479across all packages linked into a single binary,
480only that the import paths (their full file names) be unique.
481</p>
482
483<p>
484See <a href="/doc/effective_go.html#names">Effective Go</a> to learn more about
485Go's naming conventions.
486</p>
487
488
489<h2 id="Testing">Testing</h2>
490
491<p>
492Go has a lightweight test framework composed of the <code>go test</code>
493command and the <code>testing</code> package.
494</p>
495
496<p>
497You write a test by creating a file with a name ending in <code>_test.go</code>
498that contains functions named <code>TestXXX</code> with signature
499<code>func (t *testing.T)</code>.
500The test framework runs each such function;
501if the function calls a failure function such as <code>t.Error</code> or
502<code>t.Fail</code>, the test is considered to have failed.
503</p>
504
505<p>
506Add a test to the <code>stringutil</code> package by creating the file
507<code>$GOPATH/src/github.com/user/stringutil/reverse_test.go</code> containing
508the following Go code.
509</p>
510
511<pre>
512package stringutil
513
514import "testing"
515
516func TestReverse(t *testing.T) {
517 cases := []struct {
518 in, want string
519 }{
520 {"Hello, world", "dlrow ,olleH"},
521 {"Hello, 世界", "界世 ,olleH"},
522 {"", ""},
523 }
524 for _, c := range cases {
525 got := Reverse(c.in)
526 if got != c.want {
527 t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
528 }
529 }
530}
531</pre>
532
533<p>
534Then run the test with <code>go test</code>:
535</p>
536
537<pre>
538$ <b>go test github.com/user/stringutil</b>
539ok github.com/user/stringutil 0.165s
540</pre>
541
542<p>
543As always, if you are running the <code>go</code> tool from the package
544directory, you can omit the package path:
545</p>
546
547<pre>
548$ <b>go test</b>
549ok github.com/user/stringutil 0.165s
550</pre>
551
552<p>
553Run <code><a href="/cmd/go/#hdr-Test_packages">go help test</a></code> and see the
554<a href="/pkg/testing/">testing package documentation</a> for more detail.
555</p>
556
557
558<h2 id="remote">Remote packages</h2>
559
560<p>
561An import path can describe how to obtain the package source code using a
562revision control system such as Git or Mercurial. The <code>go</code> tool uses
563this property to automatically fetch packages from remote repositories.
564For instance, the examples described in this document are also kept in a
565Git repository hosted at GitHub
566<code><a href="https://github.com/golang/example">github.com/golang/example</a></code>.
567If you include the repository URL in the package's import path,
568<code>go get</code> will fetch, build, and install it automatically:
569</p>
570
571<pre>
572$ <b>go get github.com/golang/example/hello</b>
573$ <b>$GOPATH/bin/hello</b>
574Hello, Go examples!
575</pre>
576
577<p>
578If the specified package is not present in a workspace, <code>go get</code>
579will place it inside the first workspace specified by <code>GOPATH</code>.
580(If the package does already exist, <code>go get</code> skips the remote
581fetch and behaves the same as <code>go install</code>.)
582</p>
583
584<p>
585After issuing the above <code>go get</code> command, the workspace directory
586tree should now look like this:
587</p>
588
589<pre>
590bin/
591 hello # command executable
592pkg/
593 linux_amd64/
594 github.com/golang/example/
595 stringutil.a # package object
596 github.com/user/
597 stringutil.a # package object
598src/
599 github.com/golang/example/
600 .git/ # Git repository metadata
601 hello/
602 hello.go # command source
603 stringutil/
604 reverse.go # package source
605 reverse_test.go # test source
606 github.com/user/
607 hello/
608 hello.go # command source
609 stringutil/
610 reverse.go # package source
611 reverse_test.go # test source
612</pre>
613
614<p>
615The <code>hello</code> command hosted at GitHub depends on the
616<code>stringutil</code> package within the same repository. The imports in
617<code>hello.go</code> file use the same import path convention, so the
618<code>go get</code> command is able to locate and install the dependent
619package, too.
620</p>
621
622<pre>
623import "github.com/golang/example/stringutil"
624</pre>
625
626<p>
627This convention is the easiest way to make your Go packages available for
628others to use.
629The <a href="//golang.org/wiki/Projects">Go Wiki</a>
630and <a href="//godoc.org/">godoc.org</a>
631provide lists of external Go projects.
632</p>
633
634<p>
635For more information on using remote repositories with the <code>go</code> tool, see
636<code><a href="/cmd/go/#hdr-Remote_import_paths">go help importpath</a></code>.
637</p>
638
639
640<h2 id="next">What's next</h2>
641
642<p>
643Subscribe to the
644<a href="//groups.google.com/group/golang-announce">golang-announce</a>
645mailing list to be notified when a new stable version of Go is released.
646</p>
647
648<p>
649See <a href="/doc/effective_go.html">Effective Go</a> for tips on writing
650clear, idiomatic Go code.
651</p>
652
653<p>
654Take <a href="//tour.golang.org/">A Tour of Go</a> to learn the language
655proper.
656</p>
657
658<p>
659Visit the <a href="/doc/#articles">documentation page</a> for a set of in-depth
660articles about the Go language and its libraries and tools.
661</p>
662
663
664<h2 id="help">Getting help</h2>
665
666<p>
667For real-time help, ask the helpful gophers in <code>#go-nuts</code> on the
668<a href="http://freenode.net/">Freenode</a> IRC server.
669</p>
670
671<p>
672The official mailing list for discussion of the Go language is
673<a href="//groups.google.com/group/golang-nuts">Go Nuts</a>.
674</p>
675
676<p>
677Report bugs using the
678<a href="//golang.org/issue">Go issue tracker</a>.
679</p>