1 <!--{ 2 "Title": "How to Write Go Code" 3 }--> 4 5 <h2 id="Introduction">Introduction</h2> 6 7 <p> 8 This document demonstrates the development of a simple Go package and 9 introduces the <a href="/cmd/go/">go tool</a>, the standard way to fetch, 10 build, and install Go packages and commands. 11 </p> 12 13 <p> 14 The <code>go</code> tool requires you to organize your code in a specific 15 way. Please read this document carefully. 16 It explains the simplest way to get up and running with your Go installation. 17 </p> 18 19 <p> 20 A 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 27 <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> 39 Note that this differs from other programming environments in which every 40 project has a separate workspace and workspaces are closely tied to version 41 control repositories. 42 </p> 43 44 <h3 id="Workspaces">Workspaces</h3> 45 46 <p> 47 A workspace is a directory hierarchy with three directories at its root: 48 </p> 49 50 <ul> 51 <li><code>src</code> contains Go source files, 52 <li><code>pkg</code> contains package objects, and 53 <li><code>bin</code> contains executable commands. 54 </ul> 55 56 <p> 57 The <code>go</code> tool builds source packages and installs the resulting 58 binaries to the <code>pkg</code> and <code>bin</code> directories. 59 </p> 60 61 <p> 62 The <code>src</code> subdirectory typically contains multiple version control 63 repositories (such as for Git or Mercurial) that track the development of one 64 or more source packages. 65 </p> 66 67 <p> 68 To give you an idea of how a workspace looks in practice, here's an example: 69 </p> 70 71 <pre> 72 bin/ 73 hello # command executable 74 outyet # command executable 75 pkg/ 76 linux_amd64/ 77 github.com/golang/example/ 78 stringutil.a # package object 79 src/ 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 90 <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) ... 96 </pre> 97 98 <p> 99 The tree above shows a workspace containing two repositories 100 (<code>example</code> and <code>image</code>). 101 The <code>example</code> repository contains two commands (<code>hello</code> 102 and <code>outyet</code>) and one library (<code>stringutil</code>). 103 The <code>image</code> repository contains the <code>bmp</code> package 104 and <a href="https://godoc.org/golang.org/x/image">several others</a>. 105 </p> 106 107 <p> 108 A typical workspace contains many source repositories containing many 109 packages and commands. Most Go programmers keep <i>all</i> their Go source code 110 and dependencies in a single workspace. 111 </p> 112 113 <p> 114 Commands and libraries are built from different kinds of source packages. 115 We 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> 122 The <code>GOPATH</code> environment variable specifies the location of your 123 workspace. It defaults to a directory named <code>go</code> inside your home directory, 124 so <code>$HOME/go</code> on Unix, 125 <code>$home/go</code> on Plan 9, 126 and <code>%USERPROFILE%\go</code> (usually <code>C:\Users\YourName\go</code>) on Windows. 127 If 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>.) 130 Note that <code>GOPATH</code> must <b>not</b> be the 131 same path as your Go installation. 132 </p> 133 134 <p> 135 The command <code>go</code> <code>env</code> <code>GOPATH</code> 136 prints the effective current <code>GOPATH</code>; 137 it prints the default location if the environment variable is unset. 138 </p> 139 140 <p> 141 For convenience, add the workspace's <code>bin</code> subdirectory 142 to your <code>PATH</code>: 143 </p> 144 145 <pre> 146 $ <b>export PATH=$PATH:$(go env GOPATH)/bin</b> 147 </pre> 148 149 <p> 150 The scripts in the rest of this document use <code>$GOPATH</code> 151 instead of <code>$(go env GOPATH)</code> for brevity. 152 To make the scripts run as written 153 if you have not set GOPATH, 154 you can substitute $HOME/go in those commands 155 or else run: 156 </p> 157 158 <pre> 159 $ <b>export GOPATH=$(go env GOPATH)</b> 160 </pre> 161 162 <p> 163 To 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> 168 To use a custom workspace location, 169 <a href="https://golang.org/wiki/SettingGOPATH">set the <code>GOPATH</code> environment variable</a>. 170 </p> 171 172 <h3 id="ImportPaths">Import paths</h3> 173 174 <p> 175 An <i>import path</i> is a string that uniquely identifies a package. 176 A package's import path corresponds to its location inside a workspace 177 or in a remote repository (explained below). 178 </p> 179 180 <p> 181 The packages from the standard library are given short import paths such as 182 <code>"fmt"</code> and <code>"net/http"</code>. 183 For your own packages, you must choose a base path that is unlikely to 184 collide with future additions to the standard library or other external 185 libraries. 186 </p> 187 188 <p> 189 If you keep your code in a source repository somewhere, then you should use the 190 root of that source repository as your base path. 191 For 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> 196 Note that you don't need to publish your code to a remote repository before you 197 can build it. It's just a good habit to organize your code as if you will 198 publish it someday. In practice you can choose any arbitrary path name, 199 as long as it is unique to the standard library and greater Go ecosystem. 200 </p> 201 202 <p> 203 We'll use <code>github.com/user</code> as our base path. Create a directory 204 inside 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> 215 To 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 217 inside your workspace: 218 </p> 219 220 <pre> 221 $ <b>mkdir $GOPATH/src/github.com/user/hello</b> 222 </pre> 223 224 <p> 225 Next, create a file named <code>hello.go</code> inside that directory, 226 containing the following Go code. 227 </p> 228 229 <pre> 230 package main 231 232 import "fmt" 233 234 func main() { 235 fmt.Printf("Hello, world.\n") 236 } 237 </pre> 238 239 <p> 240 Now 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> 248 Note 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> 255 You can also omit the package path if you run <code>go install</code> from the 256 package 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> 265 This command builds the <code>hello</code> command, producing an executable 266 binary. It then installs that binary to the workspace's <code>bin</code> 267 directory as <code>hello</code> (or, under Windows, <code>hello.exe</code>). 268 In our example, that will be <code>$GOPATH/bin/hello</code>, which is 269 <code>$HOME/work/bin/hello</code>. 270 </p> 271 272 <p> 273 The <code>go</code> tool will only print output when an error occurs, so if 274 these commands produce no output they have executed successfully. 275 </p> 276 277 <p> 278 You 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> 283 Hello, world. 284 </pre> 285 286 <p> 287 Or, as you have added <code>$GOPATH/bin</code> to your <code>PATH</code>, 288 just type the binary name: 289 </p> 290 291 <pre> 292 $ <b>hello</b> 293 Hello, world. 294 </pre> 295 296 <p> 297 If you're using a source control system, now would be a good time to initialize 298 a repository, add the files, and commit your first change. Again, this step is 299 optional: 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> 305 Initialized empty Git repository in /home/user/work/src/github.com/user/hello/.git/ 306 $ <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> 314 Pushing 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> 321 Let's write a library and use it from the <code>hello</code> program. 322 </p> 323 324 <p> 325 Again, 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> 334 Next, create a file named <code>reverse.go</code> in that directory with the 335 following contents. 336 </p> 337 338 <pre> 339 // Package stringutil contains utility functions for working with strings. 340 package stringutil 341 342 // Reverse returns its argument string reversed rune-wise left to right. 343 func Reverse(s string) string { 344 r := []rune(s) 345 for i, j := 0, len(r)-1; i < 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> 353 Now, 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> 361 Or, 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> 369 This won't produce an output file. To do that, you must use <code>go 370 install</code>, which places the package object inside the <code>pkg</code> 371 directory of the workspace. 372 </p> 373 374 <p> 375 After confirming that the <code>stringutil</code> package builds, 376 modify 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> 381 package main 382 383 import ( 384 "fmt" 385 386 <b>"github.com/user/stringutil"</b> 387 ) 388 389 func main() { 390 fmt.Printf(stringutil.Reverse("!oG ,olleH")) 391 } 392 </pre> 393 394 <p> 395 Whenever the <code>go</code> tool installs a package or binary, it also 396 installs whatever dependencies it has. 397 So 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> 405 the <code>stringutil</code> package will be installed as well, automatically. 406 </p> 407 408 <p> 409 Running the new version of the program, you should see a new, reversed message: 410 </p> 411 412 <pre> 413 $ <b>hello</b> 414 Hello, Go! 415 </pre> 416 417 <p> 418 After the steps above, your workspace should look like this: 419 </p> 420 421 <pre> 422 bin/ 423 hello # command executable 424 pkg/ 425 linux_amd64/ # this will reflect your OS and architecture 426 github.com/user/ 427 stringutil.a # package object 428 src/ 429 github.com/user/ 430 hello/ 431 hello.go # command source 432 stringutil/ 433 reverse.go # package source 434 </pre> 435 436 <p> 437 Note that <code>go install</code> placed the <code>stringutil.a</code> object 438 in a directory inside <code>pkg/linux_amd64</code> that mirrors its source 439 directory. 440 This is so that future invocations of the <code>go</code> tool can find the 441 package object and avoid recompiling the package unnecessarily. 442 The <code>linux_amd64</code> part is there to aid in cross-compilation, 443 and will reflect the operating system and architecture of your system. 444 </p> 445 446 <p> 447 Go command executables are statically linked; the package objects need not 448 be present to run Go programs. 449 </p> 450 451 452 <h3 id="PackageNames">Package names</h3> 453 454 <p> 455 The first statement in a Go source file must be 456 </p> 457 458 <pre> 459 package <i>name</i> 460 </pre> 461 462 <p> 463 where <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> 468 Go's convention is that the package name is the last element of the 469 import path: the package imported as "<code>crypto/rot13</code>" 470 should be named <code>rot13</code>. 471 </p> 472 473 <p> 474 Executable commands must always use <code>package main</code>. 475 </p> 476 477 <p> 478 There is no requirement that package names be unique 479 across all packages linked into a single binary, 480 only that the import paths (their full file names) be unique. 481 </p> 482 483 <p> 484 See <a href="/doc/effective_go.html#names">Effective Go</a> to learn more about 485 Go's naming conventions. 486 </p> 487 488 489 <h2 id="Testing">Testing</h2> 490 491 <p> 492 Go has a lightweight test framework composed of the <code>go test</code> 493 command and the <code>testing</code> package. 494 </p> 495 496 <p> 497 You write a test by creating a file with a name ending in <code>_test.go</code> 498 that contains functions named <code>TestXXX</code> with signature 499 <code>func (t *testing.T)</code>. 500 The test framework runs each such function; 501 if 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> 506 Add 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 508 the following Go code. 509 </p> 510 511 <pre> 512 package stringutil 513 514 import "testing" 515 516 func 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> 534 Then run the test with <code>go test</code>: 535 </p> 536 537 <pre> 538 $ <b>go test github.com/user/stringutil</b> 539 ok github.com/user/stringutil 0.165s 540 </pre> 541 542 <p> 543 As always, if you are running the <code>go</code> tool from the package 544 directory, you can omit the package path: 545 </p> 546 547 <pre> 548 $ <b>go test</b> 549 ok github.com/user/stringutil 0.165s 550 </pre> 551 552 <p> 553 Run <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> 561 An import path can describe how to obtain the package source code using a 562 revision control system such as Git or Mercurial. The <code>go</code> tool uses 563 this property to automatically fetch packages from remote repositories. 564 For instance, the examples described in this document are also kept in a 565 Git repository hosted at GitHub 566 <code><a href="https://github.com/golang/example">github.com/golang/example</a></code>. 567 If 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> 574 Hello, Go examples! 575 </pre> 576 577 <p> 578 If the specified package is not present in a workspace, <code>go get</code> 579 will 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 581 fetch and behaves the same as <code>go install</code>.) 582 </p> 583 584 <p> 585 After issuing the above <code>go get</code> command, the workspace directory 586 tree should now look like this: 587 </p> 588 589 <pre> 590 bin/ 591 hello # command executable 592 pkg/ 593 linux_amd64/ 594 github.com/golang/example/ 595 stringutil.a # package object 596 github.com/user/ 597 stringutil.a # package object 598 src/ 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> 615 The <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 619 package, too. 620 </p> 621 622 <pre> 623 import "github.com/golang/example/stringutil" 624 </pre> 625 626 <p> 627 This convention is the easiest way to make your Go packages available for 628 others to use. 629 The <a href="//golang.org/wiki/Projects">Go Wiki</a> 630 and <a href="//godoc.org/">godoc.org</a> 631 provide lists of external Go projects. 632 </p> 633 634 <p> 635 For 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> 643 Subscribe to the 644 <a href="//groups.google.com/group/golang-announce">golang-announce</a> 645 mailing list to be notified when a new stable version of Go is released. 646 </p> 647 648 <p> 649 See <a href="/doc/effective_go.html">Effective Go</a> for tips on writing 650 clear, idiomatic Go code. 651 </p> 652 653 <p> 654 Take <a href="//tour.golang.org/">A Tour of Go</a> to learn the language 655 proper. 656 </p> 657 658 <p> 659 Visit the <a href="/doc/#articles">documentation page</a> for a set of in-depth 660 articles about the Go language and its libraries and tools. 661 </p> 662 663 664 <h2 id="help">Getting help</h2> 665 666 <p> 667 For 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> 672 The 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> 677 Report bugs using the 678 <a href="//golang.org/issue">Go issue tracker</a>. 679 </p> 680