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