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