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