github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/doc/code.html (about) 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 is likely the only environment variable you'll need to set 124 when developing Go code. 125 </p> 126 127 <p> 128 To get started, create a workspace directory and set <code>GOPATH</code> 129 accordingly. Your workspace can be located wherever you like, but we'll use 130 <code>$HOME/work</code> in this document. Note that this must <b>not</b> be the 131 same path as your Go installation. 132 (Another common setup is to set <code>GOPATH=$HOME</code>.) 133 </p> 134 135 <pre> 136 $ <b>mkdir $HOME/work</b> 137 $ <b>export GOPATH=$HOME/work</b> 138 </pre> 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:$GOPATH/bin</b> 147 </pre> 148 149 <p> 150 To learn more about setting up the <code>GOPATH</code> environment variable, 151 please see 152 <a href="/cmd/go/#hdr-GOPATH_environment_variable"><code>go help gopath</code></a> 153 </p> 154 155 <h3 id="ImportPaths">Import paths</h3> 156 157 <p> 158 An <i>import path</i> is a string that uniquely identifies a package. 159 A package's import path corresponds to its location inside a workspace 160 or in a remote repository (explained below). 161 </p> 162 163 <p> 164 The packages from the standard library are given short import paths such as 165 <code>"fmt"</code> and <code>"net/http"</code>. 166 For your own packages, you must choose a base path that is unlikely to 167 collide with future additions to the standard library or other external 168 libraries. 169 </p> 170 171 <p> 172 If you keep your code in a source repository somewhere, then you should use the 173 root of that source repository as your base path. 174 For 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> 179 Note that you don't need to publish your code to a remote repository before you 180 can build it. It's just a good habit to organize your code as if you will 181 publish it someday. In practice you can choose any arbitrary path name, 182 as long as it is unique to the standard library and greater Go ecosystem. 183 </p> 184 185 <p> 186 We'll use <code>github.com/user</code> as our base path. Create a directory 187 inside 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> 198 To 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 200 inside your workspace: 201 </p> 202 203 <pre> 204 $ <b>mkdir $GOPATH/src/github.com/user/hello</b> 205 </pre> 206 207 <p> 208 Next, create a file named <code>hello.go</code> inside that directory, 209 containing the following Go code. 210 </p> 211 212 <pre> 213 package main 214 215 import "fmt" 216 217 func main() { 218 fmt.Printf("Hello, world.\n") 219 } 220 </pre> 221 222 <p> 223 Now 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> 231 Note 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> 238 You can also omit the package path if you run <code>go install</code> from the 239 package 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> 248 This command builds the <code>hello</code> command, producing an executable 249 binary. It then installs that binary to the workspace's <code>bin</code> 250 directory as <code>hello</code> (or, under Windows, <code>hello.exe</code>). 251 In our example, that will be <code>$GOPATH/bin/hello</code>, which is 252 <code>$HOME/work/bin/hello</code>. 253 </p> 254 255 <p> 256 The <code>go</code> tool will only print output when an error occurs, so if 257 these commands produce no output they have executed successfully. 258 </p> 259 260 <p> 261 You 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> 266 Hello, world. 267 </pre> 268 269 <p> 270 Or, as you have added <code>$GOPATH/bin</code> to your <code>PATH</code>, 271 just type the binary name: 272 </p> 273 274 <pre> 275 $ <b>hello</b> 276 Hello, world. 277 </pre> 278 279 <p> 280 If you're using a source control system, now would be a good time to initialize 281 a repository, add the files, and commit your first change. Again, this step is 282 optional: 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> 288 Initialized empty Git repository in /home/user/work/src/github.com/user/hello/.git/ 289 $ <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> 297 Pushing 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> 304 Let's write a library and use it from the <code>hello</code> program. 305 </p> 306 307 <p> 308 Again, 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> 317 Next, create a file named <code>reverse.go</code> in that directory with the 318 following contents. 319 </p> 320 321 <pre> 322 // Package stringutil contains utility functions for working with strings. 323 package stringutil 324 325 // Reverse returns its argument string reversed rune-wise left to right. 326 func Reverse(s string) string { 327 r := []rune(s) 328 for i, j := 0, len(r)-1; i < 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> 336 Now, 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> 344 Or, 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> 352 This won't produce an output file. To do that, you must use <code>go 353 install</code>, which places the package object inside the <code>pkg</code> 354 directory of the workspace. 355 </p> 356 357 <p> 358 After confirming that the <code>stringutil</code> package builds, 359 modify 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> 364 package main 365 366 import ( 367 "fmt" 368 369 <b>"github.com/user/stringutil"</b> 370 ) 371 372 func main() { 373 fmt.Printf(stringutil.Reverse("!oG ,olleH")) 374 } 375 </pre> 376 377 <p> 378 Whenever the <code>go</code> tool installs a package or binary, it also 379 installs whatever dependencies it has. 380 So 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> 388 the <code>stringutil</code> package will be installed as well, automatically. 389 </p> 390 391 <p> 392 Running the new version of the program, you should see a new, reversed message: 393 </p> 394 395 <pre> 396 $ <b>hello</b> 397 Hello, Go! 398 </pre> 399 400 <p> 401 After the steps above, your workspace should look like this: 402 </p> 403 404 <pre> 405 bin/ 406 hello # command executable 407 pkg/ 408 linux_amd64/ # this will reflect your OS and architecture 409 github.com/user/ 410 stringutil.a # package object 411 src/ 412 github.com/user/ 413 hello/ 414 hello.go # command source 415 stringutil/ 416 reverse.go # package source 417 </pre> 418 419 <p> 420 Note that <code>go install</code> placed the <code>stringutil.a</code> object 421 in a directory inside <code>pkg/linux_amd64</code> that mirrors its source 422 directory. 423 This is so that future invocations of the <code>go</code> tool can find the 424 package object and avoid recompiling the package unnecessarily. 425 The <code>linux_amd64</code> part is there to aid in cross-compilation, 426 and will reflect the operating system and architecture of your system. 427 </p> 428 429 <p> 430 Go command executables are statically linked; the package objects need not 431 be present to run Go programs. 432 </p> 433 434 435 <h3 id="PackageNames">Package names</h3> 436 437 <p> 438 The first statement in a Go source file must be 439 </p> 440 441 <pre> 442 package <i>name</i> 443 </pre> 444 445 <p> 446 where <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> 451 Go's convention is that the package name is the last element of the 452 import path: the package imported as "<code>crypto/rot13</code>" 453 should be named <code>rot13</code>. 454 </p> 455 456 <p> 457 Executable commands must always use <code>package main</code>. 458 </p> 459 460 <p> 461 There is no requirement that package names be unique 462 across all packages linked into a single binary, 463 only that the import paths (their full file names) be unique. 464 </p> 465 466 <p> 467 See <a href="/doc/effective_go.html#names">Effective Go</a> to learn more about 468 Go's naming conventions. 469 </p> 470 471 472 <h2 id="Testing">Testing</h2> 473 474 <p> 475 Go has a lightweight test framework composed of the <code>go test</code> 476 command and the <code>testing</code> package. 477 </p> 478 479 <p> 480 You write a test by creating a file with a name ending in <code>_test.go</code> 481 that contains functions named <code>TestXXX</code> with signature 482 <code>func (t *testing.T)</code>. 483 The test framework runs each such function; 484 if 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> 489 Add 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 491 the following Go code. 492 </p> 493 494 <pre> 495 package stringutil 496 497 import "testing" 498 499 func 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> 517 Then run the test with <code>go test</code>: 518 </p> 519 520 <pre> 521 $ <b>go test github.com/user/stringutil</b> 522 ok github.com/user/stringutil 0.165s 523 </pre> 524 525 <p> 526 As always, if you are running the <code>go</code> tool from the package 527 directory, you can omit the package path: 528 </p> 529 530 <pre> 531 $ <b>go test</b> 532 ok github.com/user/stringutil 0.165s 533 </pre> 534 535 <p> 536 Run <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> 544 An import path can describe how to obtain the package source code using a 545 revision control system such as Git or Mercurial. The <code>go</code> tool uses 546 this property to automatically fetch packages from remote repositories. 547 For instance, the examples described in this document are also kept in a 548 Git repository hosted at GitHub 549 <code><a href="https://github.com/golang/example">github.com/golang/example</a></code>. 550 If 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> 557 Hello, Go examples! 558 </pre> 559 560 <p> 561 If the specified package is not present in a workspace, <code>go get</code> 562 will 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 564 fetch and behaves the same as <code>go install</code>.) 565 </p> 566 567 <p> 568 After issuing the above <code>go get</code> command, the workspace directory 569 tree should now look like this: 570 </p> 571 572 <pre> 573 bin/ 574 hello # command executable 575 pkg/ 576 linux_amd64/ 577 github.com/golang/example/ 578 stringutil.a # package object 579 github.com/user/ 580 stringutil.a # package object 581 src/ 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> 598 The <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 602 package, too. 603 </p> 604 605 <pre> 606 import "github.com/golang/example/stringutil" 607 </pre> 608 609 <p> 610 This convention is the easiest way to make your Go packages available for 611 others to use. 612 The <a href="//golang.org/wiki/Projects">Go Wiki</a> 613 and <a href="//godoc.org/">godoc.org</a> 614 provide lists of external Go projects. 615 </p> 616 617 <p> 618 For 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> 626 Subscribe to the 627 <a href="//groups.google.com/group/golang-announce">golang-announce</a> 628 mailing list to be notified when a new stable version of Go is released. 629 </p> 630 631 <p> 632 See <a href="/doc/effective_go.html">Effective Go</a> for tips on writing 633 clear, idiomatic Go code. 634 </p> 635 636 <p> 637 Take <a href="//tour.golang.org/">A Tour of Go</a> to learn the language 638 proper. 639 </p> 640 641 <p> 642 Visit the <a href="/doc/#articles">documentation page</a> for a set of in-depth 643 articles about the Go language and its libraries and tools. 644 </p> 645 646 647 <h2 id="help">Getting help</h2> 648 649 <p> 650 For 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> 655 The 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> 660 Report bugs using the 661 <a href="//golang.org/issue">Go issue tracker</a>. 662 </p>