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 &lt; 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>