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