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