mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 16:50:58 +00:00 
			
		
		
		
	 7cb21a79a4
			
		
	
	
		7cb21a79a4
		
	
	
	
	
		
			
			This allows HTML pages to specify arbitrary data in a header:
<!--{
        "Title": "The page title",
        ...
}-->
replacing the old style comments:
<!-- title The page title -->
R=gri, rsc, r, bradfitz, dsymonds
CC=golang-dev
https://golang.org/cl/5532093
		
	
			
		
			
				
	
	
		
			343 lines
		
	
	
	
		
			9.4 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			343 lines
		
	
	
	
		
			9.4 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!--{
 | |
| 	"Title": "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>
 | |
| 
 | |
| <h3>Choosing an import path</h3>
 | |
| 
 | |
| <p>
 | |
| The standard packages are given short names like <code>fmt</code> and
 | |
| <code>net/http</code> for convenience.
 | |
| For your own projects, choose a name space that is unlikely
 | |
| to collide with future additions to the standard library or other
 | |
| external libraries.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| For instance, if your source repository is at <code>example.com</code> 
 | |
| or <code>code.google.com/p/example</code>, you should begin your package
 | |
| paths with that URL, as in "<code>example.com/foo/bar</code>" or
 | |
| "<code>code.google.com/p/example/foo/bar</code>".
 | |
| This way the <a href="/cmd/go/"><code>go</code> tool</a> can automatically
 | |
| check out and build the source code from its import path.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| If you don't intend your code to be installed in this way, you should at
 | |
| least use a unique prefix like "<code>widgets/</code>", as in
 | |
| "<code>widgets/foo/bar</code>". A good rule is to use a prefix such as your
 | |
| company or project name since it is unlikely to be used by another group.
 | |
| </p>
 | |
| 
 | |
| 
 | |
| <h3>The <code>go</code> tool and <code>GOPATH</code></h3>
 | |
| 
 | |
| <p>
 | |
| The <a href="/cmd/go/"><code>go</code> tool</a> is the standard means of
 | |
| building and installing Go libraries and programs. It is a "zero configuration"
 | |
| tool; it determines how to build Go packages from their source code alone.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| To use the <code>go</code> tool effectively you must set the
 | |
| <code>GOPATH</code> variable.
 | |
| <code>GOPATH</code> specifies a list of paths that contain Go source code
 | |
| and package binaries. Source code, package objects, and command binaries are
 | |
| located inside the <code>GOPATH</code>s' <code>src</code>, <code>pkg</code>,
 | |
| and <code>bin</code> subdirectories respectively.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| You should set <code>GOPATH</code> in your shell profile
 | |
| (<code>$HOME/.bashrc</code>, <code>$HOME/.profile</code>, or equivalent).
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| This shell session demonstrates setting <code>GOPATH</code>, creating a trivial
 | |
| <code>widgets/foo</code> package, and building and installing the package.
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| $ export GOPATH=$HOME/gocode
 | |
| $ mkdir -p $GOPATH/src/widgets/foo
 | |
| $ cat > $GOPATH/src/widgets/foo/foo.go
 | |
| package foo
 | |
| const String = "Go rules!"
 | |
| ^D
 | |
| $ go install widgets/foo
 | |
| $ ls $GOPATH/pkg/*/example
 | |
| foo.a
 | |
| </pre>
 | |
| 
 | |
| <p>(<code>^D</code> means to type Control-D.)</p>
 | |
| 
 | |
| <p>
 | |
| Type <code>go help gopath</code> on the command line for more information
 | |
| about <code>GOPATH</code>.
 | |
| </p>
 | |
| 
 | |
| 
 | |
| <h3>Go source files</h3>
 | |
| 
 | |
| <p>
 | |
| The first statement in a Go source file 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>.
 | |
| There is no requirement that package names be unique
 | |
| across all packages linked into a single binary,
 | |
| only that the import paths (their full file names) be unique.
 | |
| </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>
 | |
| The <a href="/cmd/go/"><code>go</code> tool</a> treats code belonging to
 | |
| <code>package main</code> as an executable command, and installs the package
 | |
| binary to the <code>GOPATH</code>'s <code>bin</code> subdirectory.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| Building executable commands is the same as building packages.
 | |
| Use "<code>go install</code>":
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| $ cat > $GOPATH/src/widgets/bar/bar.go
 | |
| package main
 | |
| 
 | |
| import (
 | |
|     "fmt"
 | |
|     "widgets/foo"
 | |
| )
 | |
| 
 | |
| func main() {
 | |
|     fmt.Println(foo.String)
 | |
| }
 | |
| ^D
 | |
| $ go install widgets/bar
 | |
| $ $GOPATH/bin/bar
 | |
| Go rules!
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| Run <code>go help build</code> and <code>go help install</code> for more
 | |
| about building and installing Go binaries.
 | |
| </p>
 | |
| 
 | |
| <h2 id="Testing">Testing</h2>
 | |
| 
 | |
| <p>
 | |
| Go has a lightweight test framework composed of the <code>go</code> tool and
 | |
| the <code>testing</code> package.
 | |
| 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.
 | |
| Run <code>go help test</code> and see the
 | |
| <a href="/pkg/testing/">testing package documentation</a> for more detail.
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| To run the test, run "<code>go test</code>":
 | |
| </p>
 | |
| 
 | |
| <pre>
 | |
| $ cat > $GOPATH/src/widgets/foo/foo_test.go
 | |
| package foo
 | |
| 
 | |
| import "testing"
 | |
| 
 | |
| func TestString(t *testing.T) {
 | |
|     const expect = "Go rules!"
 | |
|     if String != expect {
 | |
|         t.Errorf("String == %q, want %q", String, expect)
 | |
|     }
 | |
| }
 | |
| ^D
 | |
| $ go test widgets/foo
 | |
| ok  	widgets/foo
 | |
| </pre>
 | |
| 
 | |
| <p>
 | |
| If your change affects performance, add a <code>Benchmark</code> function 
 | |
| (run <code>go help testfunc</code>) and run it using <code>go test
 | |
| -test.bench=.*</code>.
 | |
| </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 two 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>
 | |
| Running <code>go install</code> will build and install the package to
 | |
| the <code>GOPATH</code>'s <code>pkg</code> directory
 | |
| (it can then be imported by any other Go program).
 | |
| </p>
 | |
| 
 | |
| <p>
 | |
| Running <code>go test</code> will rebuild the package, including the
 | |
| <code>numbers_test.go</code> file, and then run the <code>TestDouble</code>
 | |
| function. The output "<code>ok</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>
 | |
| Run <code>go help test</code>, <code>go help testfunc</code>,
 | |
| and <code>go help testflag</code> and see the
 | |
| <a href="/pkg/testing/">testing package documentation</a> for more detail.
 | |
| </p>
 | |
| 
 | |
| <h2 id="arch_os_specific">Architecture- and operating system-specific code</h2>
 | |
| 
 | |
| <p>First, a disclaimer: very few Go packages should need to know about the
 | |
| hardware and operating system they run on.  In the vast majority of cases the
 | |
| language and standard library handle most portability issues.  This section is
 | |
| a guide for experienced systems programmers who have a good reason to write
 | |
| platform-specific code, such as assembly-language support for fast
 | |
| trigonometric functions or code that implements a common interface above
 | |
| different operating systems.</p>
 | |
| 
 | |
| <p>To compile such code, use the <code>$GOOS</code> and <code>$GOARCH</code>
 | |
| <a href="/doc/install.html#environment">environment variables</a> in your
 | |
| source file names.</p>
 | |
| 
 | |
| <p>For example, consider the package <code>foo</code> that consists of four
 | |
| files:</p>
 | |
| 
 | |
| <pre>
 | |
| foo.go
 | |
| foo_386.go
 | |
| foo_amd64.go
 | |
| foo_arm.go
 | |
| </pre>
 | |
| 
 | |
| describes a package that builds on
 | |
| different operating systems by parameterizing the file name with
 | |
| <code>$GOOS</code>.</p>
 | |
| 
 | |
| <p>The general code goes in <code>foo.go</code>, while architecture-specific
 | |
| code goes in <code>foo_386.go</code>, <code>foo_amd64.go</code>, and
 | |
| <code>foo_arm.go</code>.</p>
 | |
| 
 | |
| <p>If you follow these conventional parameterizations, tools such as the <a
 | |
| href="/cmd/go/"><code>go</code> tool</a> will work seamlessly with your
 | |
| package:</p>
 | |
| 
 | |
| <pre>
 | |
| foo_$GOOS.go
 | |
| foo_$GOARCH.go
 | |
| foo_$GOOS_$GOARCH.go
 | |
| </pre>
 | |
| 
 | |
| <p>The same holds for <code>.s</code> (assembly) and <code>.c</code> files.</p>
 |