github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/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="http://www.youtube.com/watch?v=XCsL89YtqCs">screencast</a>. 22 </p> 23 24 25 <h2 id="Organization">Code organization</h2> 26 27 <h3 id="Workspaces">Workspaces</h3> 28 29 <p> 30 The <code>go</code> tool is designed to work with open source code maintained 31 in public repositories. Although you don't need to publish your code, the model 32 for how the environment is set up works the same whether you do or not. 33 </p> 34 35 <p> 36 Go code must be kept inside a <i>workspace</i>. 37 A workspace is a directory hierarchy with three directories at its root: 38 </p> 39 40 <ul> 41 <li><code>src</code> contains Go source files organized into packages (one package per directory), 42 <li><code>pkg</code> contains package objects, and 43 <li><code>bin</code> contains executable commands. 44 </ul> 45 46 <p> 47 The <code>go</code> tool builds source packages and installs the resulting 48 binaries to the <code>pkg</code> and <code>bin</code> directories. 49 </p> 50 51 <p> 52 The <code>src</code> subdirectory typically contains multiple version control 53 repositories (such as for Git or Mercurial) that track the development of one 54 or more source packages. 55 </p> 56 57 <p> 58 To give you an idea of how a workspace looks in practice, here's an example: 59 </p> 60 61 <pre> 62 bin/ 63 streak # command executable 64 todo # command executable 65 pkg/ 66 linux_amd64/ 67 code.google.com/p/goauth2/ 68 oauth.a # package object 69 github.com/nf/todo/ 70 task.a # package object 71 src/ 72 code.google.com/p/goauth2/ 73 .hg/ # mercurial repository metadata 74 oauth/ 75 oauth.go # package source 76 oauth_test.go # test source 77 github.com/nf/ 78 streak/ 79 .git/ # git repository metadata 80 oauth.go # command source 81 streak.go # command source 82 todo/ 83 .git/ # git repository metadata 84 task/ 85 task.go # package source 86 todo.go # command source 87 </pre> 88 89 <p> 90 This workspace contains three repositories (<code>goauth2</code>, 91 <code>streak</code>, and <code>todo</code>) comprising two commands 92 (<code>streak</code> and <code>todo</code>) and two libraries 93 (<code>oauth</code> and <code>task</code>). 94 </p> 95 96 <p> 97 Commands and libraries are built from different kinds of source packages. 98 We will discuss the distinction <a href="#PackageNames">later</a>. 99 </p> 100 101 102 <h3 id="GOPATH">The <code>GOPATH</code> environment variable</h3> 103 104 <p> 105 The <code>GOPATH</code> environment variable specifies the location of your 106 workspace. It is likely the only environment variable you'll need to set 107 when developing Go code. 108 </p> 109 110 <p> 111 To get started, create a workspace directory and set <code>GOPATH</code> 112 accordingly. Your workspace can be located wherever you like, but we'll use 113 <code>$HOME/go</code> in this document. Note that this must <b>not</b> be the 114 same path as your Go installation. 115 </p> 116 117 <pre> 118 $ <b>mkdir $HOME/go</b> 119 $ <b>export GOPATH=$HOME/go</b> 120 </pre> 121 122 <p> 123 For convenience, add the workspace's <code>bin</code> subdirectory 124 to your <code>PATH</code>: 125 </p> 126 127 <pre> 128 $ <b>export PATH=$PATH:$GOPATH/bin</b> 129 </pre> 130 131 132 <h3 id="PackagePaths">Package paths</h3> 133 134 <p> 135 The packages from the standard library are given short paths such as 136 <code>"fmt"</code> and <code>"net/http"</code>. 137 For your own packages, you must choose a base path that is unlikely to 138 collide with future additions to the standard library or other external 139 libraries. 140 </p> 141 142 <p> 143 If you keep your code in a source repository somewhere, then you should use the 144 root of that source repository as your base path. 145 For instance, if you have a <a href="https://github.com/">GitHub</a> account at 146 <code>github.com/user</code>, that should be your base path. 147 </p> 148 149 <p> 150 Note that you don't need to publish your code to a remote repository before you 151 can build it. It's just a good habit to organize your code as if you will 152 publish it someday. In practice you can choose any arbitrary path name, 153 as long as it is unique to the standard library and greater Go ecosystem. 154 </p> 155 156 <p> 157 We'll use <code>github.com/user</code> as our base path. Create a directory 158 inside your workspace in which to keep source code: 159 </p> 160 161 <pre> 162 $ <b>mkdir -p $GOPATH/src/github.com/user</b> 163 </pre> 164 165 166 <h3 id="Command">Your first program</h3> 167 168 <p> 169 To compile and run a simple program, first choose a package path (we'll use 170 <code>github.com/user/hello</code>) and create a corresponding package directory 171 inside your workspace: 172 </p> 173 174 <pre> 175 $ <b>mkdir $GOPATH/src/github.com/user/hello</b> 176 </pre> 177 178 <p> 179 Next, create a file named <code>hello.go</code> inside that directory, 180 containing the following Go code. 181 </p> 182 183 <pre> 184 package main 185 186 import "fmt" 187 188 func main() { 189 fmt.Printf("Hello, world.\n") 190 } 191 </pre> 192 193 <p> 194 Now you can build and install that program with the <code>go</code> tool: 195 </p> 196 197 <pre> 198 $ <b>go install github.com/user/hello</b> 199 </pre> 200 201 <p> 202 Note that you can run this command from anywhere on your system. The 203 <code>go</code> tool finds the source code by looking for the 204 <code>github.com/user/hello</code> package inside the workspace specified by 205 <code>GOPATH</code>. 206 </p> 207 208 <p> 209 You can also omit the package path if you run <code>go install</code> from the 210 package directory: 211 </p> 212 213 <pre> 214 $ <b>cd $GOPATH/src/github.com/user/hello</b> 215 $ <b>go install</b> 216 </pre> 217 218 <p> 219 This command builds the <code>hello</code> command, producing an executable 220 binary. It then installs that binary to the workspace's <code>bin</code> 221 directory as <code>hello</code> (or, under Windows, <code>hello.exe</code>). 222 In our example, that will be <code>$GOPATH/bin/hello</code>, which is 223 <code>$HOME/go/bin/hello</code>. 224 </p> 225 226 <p> 227 The <code>go</code> tool will only print output when an error occurs, so if 228 these commands produce no output they have executed successfully. 229 </p> 230 231 <p> 232 You can now run the program by typing its full path at the command line: 233 </p> 234 235 <pre> 236 $ <b>$GOPATH/bin/hello</b> 237 Hello, world. 238 </pre> 239 240 <p> 241 Or, as you have added <code>$GOPATH/bin</code> to your <code>PATH</code>, 242 just type the binary name: 243 </p> 244 245 <pre> 246 $ <b>hello</b> 247 Hello, world. 248 </pre> 249 250 <p> 251 If you're using a source control system, now would be a good time to initialize 252 a repository, add the files, and commit your first change. Again, this step is 253 optional: you do not need to use source control to write Go code. 254 </p> 255 256 <pre> 257 $ <b>cd $GOPATH/src/github.com/user/hello</b> 258 $ <b>git init</b> 259 Initialized empty Git repository in /home/user/go/src/github.com/user/hello/.git/ 260 $ <b>git add hello.go</b> 261 $ <b>git commit -m "initial commit"</b> 262 [master (root-commit) 0b4507d] initial commit 263 1 file changed, 1 insertion(+) 264 create mode 100644 hello.go 265 </pre> 266 267 <p> 268 Pushing the code to a remote repository is left as an exercise for the reader. 269 </p> 270 271 272 <h3 id="Library">Your first library</h3> 273 274 <p> 275 Let's write a library and use it from the <code>hello</code> program. 276 </p> 277 278 <p> 279 Again, the first step is to choose a package path (we'll use 280 <code>github.com/user/newmath</code>) and create the package directory: 281 </p> 282 283 <pre> 284 $ <b>mkdir $GOPATH/src/github.com/user/newmath</b> 285 </pre> 286 287 <p> 288 Next, create a file named <code>sqrt.go</code> in that directory with the 289 following contents. 290 </p> 291 292 <pre> 293 // Package newmath is a trivial example package. 294 package newmath 295 296 // Sqrt returns an approximation to the square root of x. 297 func Sqrt(x float64) float64 { 298 z := 1.0 299 for i := 0; i < 1000; i++ { 300 z -= (z*z - x) / (2 * z) 301 } 302 return z 303 } 304 </pre> 305 306 <p> 307 Now, test that the package compiles with <code>go build</code>: 308 </p> 309 310 <pre> 311 $ <b>go build github.com/user/newmath</b> 312 </pre> 313 314 <p> 315 Or, if you are working in the package's source directory, just: 316 </p> 317 318 <pre> 319 $ <b>go build</b> 320 </pre> 321 322 <p> 323 This won't produce an output file. To do that, you must use <code>go 324 install</code>, which places the package object inside the <code>pkg</code> 325 directory of the workspace. 326 </p> 327 328 <p> 329 After confirming that the <code>newmath</code> package builds, 330 modify your original <code>hello.go</code> (which is in 331 <code>$GOPATH/src/github.com/user/hello</code>) to use it: 332 </p> 333 334 <pre> 335 package main 336 337 import ( 338 "fmt" 339 340 <b>"github.com/user/newmath"</b> 341 ) 342 343 func main() { 344 fmt.Printf("Hello, world. <b>Sqrt(2) = %v\n", newmath.Sqrt(2)</b>) 345 } 346 </pre> 347 348 <p> 349 Whenever the <code>go</code> tool installs a package or binary, it also 350 installs whatever dependencies it has. So when you install the <code>hello</code> 351 program 352 </p> 353 354 <pre> 355 $ <b>go install github.com/user/hello</b> 356 </pre> 357 358 <p> 359 the <code>newmath</code> package will be installed as well, automatically. 360 </p> 361 362 <p> 363 Running the new version of the program, you should see some numerical output: 364 </p> 365 366 <pre> 367 $ <b>hello</b> 368 Hello, world. Sqrt(2) = 1.414213562373095 369 </pre> 370 371 <p> 372 After the steps above, your workspace should look like this: 373 </p> 374 375 <pre> 376 bin/ 377 hello # command executable 378 pkg/ 379 linux_amd64/ # this will reflect your OS and architecture 380 github.com/user/ 381 newmath.a # package object 382 src/ 383 github.com/user/ 384 hello/ 385 hello.go # command source 386 newmath/ 387 sqrt.go # package source 388 </pre> 389 390 <p> 391 Note that <code>go install</code> placed the <code>newmath.a</code> object in a 392 directory inside <code>pkg/linux_amd64</code> that mirrors its source 393 directory. 394 This is so that future invocations of the <code>go</code> tool can find the 395 package object and avoid recompiling the package unnecessarily. 396 The <code>linux_amd64</code> part is there to aid in cross-compilation, 397 and will reflect the operating system and architecture of your system. 398 </p> 399 400 <p> 401 Go command executables are statically linked; the package objects need not 402 be present to run Go programs. 403 </p> 404 405 406 <h3 id="PackageNames">Package names</h3> 407 408 <p> 409 The first statement in a Go source file must be 410 </p> 411 412 <pre> 413 package <i>name</i> 414 </pre> 415 416 <p> 417 where <code><i>name</i></code> is the package's default name for imports. 418 (All files in a package must use the same <code><i>name</i></code>.) 419 </p> 420 421 <p> 422 Go's convention is that the package name is the last element of the 423 import path: the package imported as "<code>crypto/rot13</code>" 424 should be named <code>rot13</code>. 425 </p> 426 427 <p> 428 Executable commands must always use <code>package main</code>. 429 </p> 430 431 <p> 432 There is no requirement that package names be unique 433 across all packages linked into a single binary, 434 only that the import paths (their full file names) be unique. 435 </p> 436 437 <p> 438 See <a href="/doc/effective_go.html#names">Effective Go</a> to learn more about 439 Go's naming conventions. 440 </p> 441 442 443 <h2 id="Testing">Testing</h2> 444 445 <p> 446 Go has a lightweight test framework composed of the <code>go test</code> 447 command and the <code>testing</code> package. 448 </p> 449 450 <p> 451 You write a test by creating a file with a name ending in <code>_test.go</code> 452 that contains functions named <code>TestXXX</code> with signature 453 <code>func (t *testing.T)</code>. 454 The test framework runs each such function; 455 if the function calls a failure function such as <code>t.Error</code> or 456 <code>t.Fail</code>, the test is considered to have failed. 457 </p> 458 459 <p> 460 Add a test to the <code>newmath</code> package by creating the file 461 <code>$GOPATH/src/github.com/user/newmath/sqrt_test.go</code> containing the 462 following Go code. 463 </p> 464 465 <pre> 466 package newmath 467 468 import "testing" 469 470 func TestSqrt(t *testing.T) { 471 const in, out = 4, 2 472 if x := Sqrt(in); x != out { 473 t.Errorf("Sqrt(%v) = %v, want %v", in, x, out) 474 } 475 } 476 </pre> 477 478 <p> 479 Then run the test with <code>go test</code>: 480 </p> 481 482 <pre> 483 $ <b>go test github.com/user/newmath</b> 484 ok github.com/user/newmath 0.165s 485 </pre> 486 487 <p> 488 As always, if you are running the <code>go</code> tool from the package 489 directory, you can omit the package path: 490 </p> 491 492 <pre> 493 $ <b>go test</b> 494 ok github.com/user/newmath 0.165s 495 </pre> 496 497 <p> 498 Run <code><a href="/cmd/go/#hdr-Test_packages">go help test</a></code> and see the 499 <a href="/pkg/testing/">testing package documentation</a> for more detail. 500 </p> 501 502 503 <h2 id="remote">Remote packages</h2> 504 505 <p> 506 An import path can describe how to obtain the package source code using a 507 revision control system such as Git or Mercurial. The <code>go</code> tool uses 508 this property to automatically fetch packages from remote repositories. 509 For instance, the examples described in this document are also kept in a 510 Mercurial repository hosted at Google Code, 511 <code><a href="http://code.google.com/p/go.example">code.google.com/p/go.example</a></code>. 512 If you include the repository URL in the package's import path, 513 <code>go get</code> will fetch, build, and install it automatically: 514 </p> 515 516 <pre> 517 $ <b>go get code.google.com/p/go.example/hello</b> 518 $ <b>$GOPATH/bin/hello</b> 519 Hello, world. Sqrt(2) = 1.414213562373095 520 </pre> 521 522 <p> 523 If the specified package is not present in a workspace, <code>go get</code> 524 will place it inside the first workspace specified by <code>GOPATH</code>. 525 (If the package does already exist, <code>go get</code> skips the remote 526 fetch and behaves the same as <code>go install</code>.) 527 </p> 528 529 <p> 530 After issuing the above <code>go get</code> command, the workspace directory 531 tree should now look like this: 532 </p> 533 534 <pre> 535 bin/ 536 hello # command executable 537 pkg/ 538 linux_amd64/ 539 code.google.com/p/go.example/ 540 newmath.a # package object 541 github.com/user/ 542 newmath.a # package object 543 src/ 544 code.google.com/p/go.example/ 545 hello/ 546 hello.go # command source 547 newmath/ 548 sqrt.go # package source 549 sqrt_test.go # test source 550 github.com/user/ 551 hello/ 552 hello.go # command source 553 newmath/ 554 sqrt.go # package source 555 sqrt_test.go # test source 556 </pre> 557 558 <p> 559 The <code>hello</code> command hosted at Google Code depends on the 560 <code>newmath</code> package within the same repository. The imports in 561 <code>hello.go</code> file use the same import path convention, so the <code>go 562 get</code> command is able to locate and install the dependent package, too. 563 </p> 564 565 <pre> 566 import "code.google.com/p/go.example/newmath" 567 </pre> 568 569 <p> 570 This convention is the easiest way to make your Go packages available for 571 others to use. 572 The <a href="http://code.google.com/p/go-wiki/wiki/Projects">Go Wiki</a> 573 and <a href="http://godoc.org/">godoc.org</a> 574 provide lists of external Go projects. 575 </p> 576 577 <p> 578 For more information on using remote repositories with the <code>go</code> tool, see 579 <code><a href="/cmd/go/#hdr-Remote_import_path_syntax">go help remote</a></code>. 580 </p> 581 582 583 <h2 id="more">Further reading</h2> 584 585 <p> 586 See <a href="/doc/effective_go.html">Effective Go</a> for tips on writing 587 clear, idiomatic Go code. 588 </p> 589 590 <p> 591 Take <a href="http://tour.golang.org/">A Tour of Go</a> to learn the language 592 proper. 593 </p> 594 595 <p> 596 Visit the <a href="/doc/#articles">documentation page</a> for a set of in-depth 597 articles about the Go language and its libraries and tools. 598 </p>