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