mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 08:40:55 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			324 lines
		
	
	
	
		
			9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			324 lines
		
	
	
	
		
			9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!-- How to Write Go Code -->
 | |
| 
 | |
| <h2 id="Introduction">Introduction</h2>
 | |
| 
 | |
| <p>
 | |
| This document explains how to write a new package
 | |
| and how to test code.
 | |
| It assumes you have installed Go using the
 | |
| <a href="install.html">installation instructions</a>.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| Before embarking on a change to an existing
 | |
| package or the creation of a new package,
 | |
| be sure to send mail to the
 | |
| <a href="http://groups.google.com/group/golang-nuts">mailing list</a>
 | |
| to let people know what you are thinking of doing.
 | |
| Doing so helps avoid duplication of effort and
 | |
| enables discussions about design before any code
 | |
| has been written.
 | |
| </p>
 | |
| 
 | |
| <h2 id="Community_resources">Community resources</h2>
 | |
| 
 | |
| <p>
 | |
| For real-time help, there may be users or developers on
 | |
| <code>#go-nuts</code> on the <a href="http://freenode.net/">Freenode</a> IRC server.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| The official mailing list for discussion of the Go language is
 | |
| <a href="http://groups.google.com/group/golang-nuts">Go Nuts</a>.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| Bugs can be reported using the <a href="http://code.google.com/p/go/issues/list">Go issue tracker</a>.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| For those who wish to keep up with development,
 | |
| there is another mailing list, <a href="http://groups.google.com/group/golang-checkins">golang-checkins</a>,
 | |
| that receives a message summarizing each checkin to the Go repository.
 | |
| </p>
 | |
| 
 | |
| 
 | |
| <h2 id="New_package">Creating a new package</h2>
 | |
| 
 | |
| <p>
 | |
| The source code for the package with import path
 | |
| <code>x/y</code> is, by convention, kept in the
 | |
| directory <code>$GOROOT/src/pkg/x/y</code>.
 | |
| </p>
 | |
| 
 | |
| <h3>Makefile</h3>
 | |
| 
 | |
| <p>
 | |
| It would be nice to have Go-specific tools that
 | |
| inspect the source files to determine what to build and in
 | |
| what order, but for now, Go uses GNU <code>make</code>.
 | |
| Thus, the first file to create in a new package directory is
 | |
| usually the <code>Makefile</code>.
 | |
| The basic form used in the Go source tree
 | |
| is illustrated by <a href="../src/pkg/container/vector/Makefile"><code>src/pkg/container/vector/Makefile</code></a>:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| include ../../../Make.inc
 | |
| 
 | |
| TARG=container/vector
 | |
| GOFILES=\
 | |
| 	intvector.go\
 | |
| 	stringvector.go\
 | |
| 	vector.go\
 | |
| 
 | |
| include ../../../Make.pkg
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Outside the Go source tree (for personal packages), the standard form is
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| include $(GOROOT)/src/Make.inc
 | |
| 
 | |
| TARG=mypackage
 | |
| GOFILES=\
 | |
| 	my1.go\
 | |
| 	my2.go\
 | |
| 
 | |
| include $(GOROOT)/src/Make.pkg
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| The first and last lines <code>include</code> standard definitions and rules.
 | |
| Packages maintained in the standard Go tree use a relative path (instead of
 | |
| <code>$(GOROOT)/src</code>) so that <code>make</code> will work correctly
 | |
| even if <code>$(GOROOT)</code> contains spaces.
 | |
| This makes it easy for programmers to try Go.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| If you have not set <code>$GOROOT</code> in your environment,
 | |
| you must run <code>gomake</code> to use this form of makefile.
 | |
| <code>Gomake</code> also takes care to invoke GNU Make
 | |
| even on systems where it is installed as <code>gmake</code>
 | |
| rather than <code>make</code>.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| <code>TARG</code> is the target install path for the package,
 | |
| the string that clients will use to import it.
 | |
| Inside the Go tree, this string should be the same as the directory
 | |
| in which the <code>Makefile</code> appears, with the
 | |
| <code>$GOROOT/src/pkg/</code> prefix removed.
 | |
| Outside the Go tree, you can use any <code>TARG</code> you
 | |
| want that doesn't conflict with the standard Go package names.
 | |
| A common convention is to use an identifying top-level name
 | |
| to group your packages: <code>myname/tree</code>, <code>myname/filter</code>, etc.
 | |
| Note that even if you keep your package source outside the
 | |
| Go tree, running <code>make install</code> installs your
 | |
| package binaries in the standard location—<code>$GOROOT/pkg</code>—to
 | |
| make it easy to find them.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| <code>GOFILES</code> is a list of source files to compile to
 | |
| create the package.  The trailing <code>\</code> characters
 | |
| allow the list to be split onto multiple lines
 | |
| for easy sorting.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| If you create a new package directory in the Go tree, add it to the list in
 | |
| <code>$GOROOT/src/pkg/Makefile</code> so that it
 | |
| is included in the standard build.  Then run:
 | |
| <pre>
 | |
| cd $GOROOT/src/pkg
 | |
| ./deps.bash
 | |
| </pre>
 | |
| <p>
 | |
| to update the dependency file <code>Make.deps</code>.
 | |
| (This happens automatically each time you run <code>all.bash</code>
 | |
| or <code>make.bash</code>.)
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| If you change the imports of an existing package,
 | |
| you do not need to edit <code>$GOROOT/src/pkg/Makefile</code>
 | |
| but you will still need to run <code>deps.bash</code> as above.
 | |
| </p>
 | |
| 
 | |
| 
 | |
| <h3>Go source files</h3>
 | |
| 
 | |
| <p>
 | |
| The first statement in each of the source files listed in the <code>Makefile</code>
 | |
| should be <code>package <i>name</i></code>, where <code><i>name</i></code>
 | |
| is the package's default name for imports.
 | |
| (All files in a package must use the same <code><i>name</i></code>.)
 | |
| Go's convention is that the package name is the last element of the
 | |
| import path: the package imported as <code>"crypto/rot13"</code>
 | |
| should be named <code>rot13</code>.
 | |
| At the moment, the Go tools impose a restriction that package names are unique
 | |
| across all packages linked into a single binary, but that restriction
 | |
| will be lifted soon.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| Go compiles all the source files in a package at once, so one file
 | |
| can refer to constants, variables, types, and functions in another
 | |
| file without special arrangement or declarations.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| Writing clean, idiomatic Go code is beyond the scope of this document.
 | |
| <a href="effective_go.html">Effective Go</a> is an introduction to
 | |
| that topic.
 | |
| </p>
 | |
| 
 | |
| <h2 id="Building_programs">Building programs</h2>
 | |
| <p>To build a Go program with gomake, create a Makefile alongside your program's
 | |
| source files. It should be similar to the example above, but include
 | |
| <code>Make.cmd</code> instead of <code>Make.pkg</code>:
 | |
| 
 | |
| <pre>
 | |
| include $(GOROOT)/src/Make.inc
 | |
| 
 | |
| TARG=helloworld
 | |
| GOFILES=\
 | |
| 	helloworld.go\
 | |
| 
 | |
| include $(GOROOT)/src/Make.cmd
 | |
| </pre>
 | |
| 
 | |
| <p>Running <code>gomake</code> will compile <code>helloworld.go</code>
 | |
| and produce an executable named <code>helloworld</code> in the current
 | |
| directory.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| Running <code>gomake install</code> will build <code>helloworld</code> if
 | |
| necessary and copy it to the <code>$GOBIN</code> directory
 | |
| (<code>$GOROOT/bin/</code> is the default).
 | |
| </p>
 | |
| 
 | |
| <h2 id="Testing">Testing</h2>
 | |
| 
 | |
| <p>
 | |
| Go has a lightweight test framework known as <code>gotest</code>.
 | |
| You write a test by creating a file with a name ending in <code>_test.go</code>
 | |
| that contains functions named <code>TestXXX</code> with signature <code>func (t *testing.T)</code>.
 | |
| The test framework runs each such function;
 | |
| if the function calls a failure function such as <code>t.Error</code> or <code>t.Fail</code>, the test is considered to have failed.
 | |
| The <a href="/cmd/gotest/">gotest command documentation</a>
 | |
| and the <a href="/pkg/testing/">testing package documentation</a> give more detail.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| The <code>*_test.go</code> files should not be listed in the <code>Makefile</code>.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| To run the test, run either <code>make test</code> or <code>gotest</code>
 | |
| (they are equivalent).
 | |
| To run only the tests in a single test file, for instance <code>one_test.go</code>,
 | |
| run <code>gotest one_test.go</code>.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| If your change affects performance, add a <code>Benchmark</code> function 
 | |
| (see the <a href="/cmd/gotest/">gotest command documentation</a>)
 | |
| and run it using <code>gotest -benchmarks=.</code>.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| Once your new code is tested and working,
 | |
| it's time to get it <a href="contribute.html">reviewed and submitted</a>.
 | |
| </p>
 | |
| 
 | |
| <h2 id="pkg_example">An example package with tests</h2>
 | |
| 
 | |
| <p>
 | |
| This example package, <code>numbers</code>, consists of the function
 | |
| <code>Double</code>, which takes an <code>int</code> and returns that value 
 | |
| multiplied by 2. It consists of three files.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| First, the package implementation, <code>numbers.go</code>:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| package numbers
 | |
| 
 | |
| func Double(i int) int {
 | |
| 	return i * 2
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Next, the tests, <code>numbers_test.go</code>:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| package numbers
 | |
| 
 | |
| import (
 | |
| 	"testing"
 | |
| )
 | |
| 
 | |
| type doubleTest struct {
 | |
| 	in, out int
 | |
| }
 | |
| 
 | |
| var doubleTests = []doubleTest{
 | |
| 	doubleTest{1, 2},
 | |
| 	doubleTest{2, 4},
 | |
| 	doubleTest{-5, -10},
 | |
| }
 | |
| 
 | |
| func TestDouble(t *testing.T) {
 | |
| 	for _, dt := range doubleTests {
 | |
| 		v := Double(dt.in)
 | |
| 		if v != dt.out {
 | |
| 			t.Errorf("Double(%d) = %d, want %d.", dt.in, v, dt.out)
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Finally, the <code>Makefile</code>:
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| include $(GOROOT)/src/Make.inc
 | |
| 
 | |
| TARG=numbers
 | |
| GOFILES=\
 | |
| 	numbers.go\
 | |
| 
 | |
| include $(GOROOT)/src/Make.pkg
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Running <code>gomake install</code> will build and install the package to
 | |
| the <code>$GOROOT/pkg/</code> directory (it can then be used by any
 | |
| program on the system).
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| Running <code>gomake test</code> (or just running the command
 | |
| <code>gotest</code>) will rebuild the package, including the
 | |
| <code>numbers_test.go</code> file, and then run the <code>TestDouble</code>
 | |
| function. The output "<code>PASS</code>" indicates that all tests passed
 | |
| successfully.  Breaking the implementation by changing the multiplier from
 | |
| <code>2</code> to <code>3</code> will allow you to see how failing tests are 
 | |
| reported.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| See the <a href="/cmd/gotest/">gotest documentation</a> and the 
 | |
| <a href="/pkg/testing/">testing package</a> for more detail.
 | |
| </p>
 | 
