1
0

code.html 18 KB

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