Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Tree: 0abcbfa0bc
Fetching contributors…

Cannot retrieve contributors at this time

376 lines (332 sloc) 15.3 KB
\epi{``\lstinline{^}''}{\textit{Answer to whether there is a bit wise negation
operator.}\\\textsc{KEN THOMPSON}}
\noindent{}Packages are a collection of functions and data.
You declare a package with the
\first{\key{package}}{keyword!package} keyword. The file name does not
have to match the package name.
The convention for package names is to use
lowercase characters.
Go packages may consist of multiple files,
but they share the \lstinline{package <name>} line.
Let's define a package \package{even}\index{package!even} in the file \prog{even.go}.
\lstinputlisting[label=src:even,caption=A small package]{src/even.go}
Names that start with a capital letter are \emph{exported} and may be used
outside your package, more on that later.
Now we just need to build the package. We create a directory under \var{\$GOPATH},
copy the \file{even.go} to there (see ``\titleref{sec:building a program}'' in chapter \ref{chap:basics}).
\pr \user{mkdir $GOPATH/src/even} \coderemark{Create top-level directory}
\pr \user{cp even.go $GOPATH/src/even} \coderemark{Copy the package file}
\pr \user{go build} \coderemark{Build it}
\pr \user{go install} \coderemark{Install it to \file{../pkg}}
Next we can use the package in our own program \prog{myeven.go}:
\lstinputlisting[label=src:myeven,caption=Use of the even package]{src/myeven.go}
\pr \user{go build myeven.go}
\pr \user{./myeven}
Is 5 even? false
In Go, a function from a package is exported (visible
outside the package, i.e. public) when the first letter of the function name is a capital, hence
the function name \func{\emph{E}ven}. If we change our \prog{myeven.go} on line
10 to using the unexported function \func{even.odd}:
\noindent\lstinline{fmt.Printf("Is %d even? %v\n", i, even.odd(i))}
We get an error when compiling, because we are trying to use a
\emph{private} function:
myeven.go:10: cannot refer to unexported name even.odd
\noindent{}To summarize:
\item Public functions have a name starting with a \emph{capital}
\item Private function have a name starting with a \emph{lowercase} letter.
This convention also holds true for other names (new types, global
variables) you define in a package. Note that the term ``capital'' is not limited
to US ASCII, it extends into the entire Unicode range. So capital Greek, Coptic, etc. is OK too.
Names are as important in Go as in any other language. In some cases
they even have semantic effect: for instance, the visibility of a name
outside a package is determined by whether its first character is upper
case. It's therefore worth spending a little time talking about naming
conventions in Go programs.
The convention that is used was to leave well-known legacy
not-quite-words alone rather than try to figure out where
the capital letters go. \lstinline{Atoi}, \lstinline{Getwd},
Camelcasing works best when you have whole words
to work with: \lstinline{ReadFile, NewWriter, MakeSlice}.
\subsection{Package names}
When a package is imported (with \first{\key{import}}{keyword!import}), the package name becomes
an accessor for the contents. After\index{package!bytes}
import "bytes"
the importing package can talk about \func{bytes.Buffer}. It's helpful if
everyone using the package can use the same name to refer to its
contents, which implies that the package name should be good: short,
concise, and evocative. By convention, packages are given lower case,
single-word names; there should be no need for underscores or mixedCaps.
Err on the side of brevity, since everyone using your package will be
typing that name. And don't worry about collisions a priori. The package
name is only the default name for imports. With the above import
you can use \lstinline{bytes.Buffer}. With
import bar "bytes"
it becomes \lstinline{bar.Buffer}.
So it does need not be unique across
all source code, and in the rare case of a collision the importing
package can choose a different name to use locally. In any case,
confusion is rare because the file name in the import determines just
which package is being used.
Another convention is that the package name is the base name of its
source directory; the package in \package{src/pkg/compress/gzip} is imported as
\var{compress/gzip} but has name \package{gzip}, not
\package{compress\_gzip} and not
The importer of a package will use the name to refer to its contents, so
exported names in the package can use that fact to avoid
stutter. For instance, the buffered reader type in the
package is
called \func{Reader}, not \func{BufReader}, because users see it as
which is a clear, concise name. Moreover, because imported entities are
always addressed with their package name, \func{bufio.Reader} does not conflict
with \func{io.Reader}. Similarly, the function to make new instances of
\func{ring.Ring} (package \package{container/ring}) ---which is the definition of a constructor in Go---would normally
be called \func{NewRing}, but since \type{Ring} is the only type exported by the
package, and since the package is called
\package{ring}\index{package!ring}, it's called
just \func{New}.
Clients of the package see that as \func{ring.New}. Use the package structure
to help you choose good names.
Another short example is \func{once.Do} (see package \package{sync}); \func{once.Do(setup)} reads well and would
not be improved by writing \lstinline{once.DoOrWaitUntilDone(setup)}. Long names
don't automatically make things more readable. If the name represents
something intricate or subtle, it's usually better to write a helpful
doc comment than to attempt to put all the information into the name.
Finally, the convention in Go is to use \first{MixedCaps}{MixedCaps} or mixedCaps rather
than underscores to write multi-word names.
%% Advanced Go, leave it
%%Every source file in a package can define an \func{init()} function. This function is
%%called after the variables in the package have gotten their value. The
%%\func{init()} function can be used to setup state before the execution
\section{Documenting packages}
\gomarginpar{This text is copied from \cite{effective_go}.}
Every package should have a \emph{package comment}, a block comment preceding the
\key{package} clause. For multi-file packages, the package comment only needs to be
present in one file, and any one will do. The package comment should introduce
the package and provide information relevant to the package as a whole. It will
appear first on the \prog{go doc} page and should set up the detailed documentation
that follows. An example from the official \package{regexp} package:
The regexp package implements a simple library for
regular expressions.
The syntax of the regular expressions accepted is:
concatenation { '|' concatenation }
package regexp
Each defined (and exported) function should have a small line of text
documenting the behavior of the function. An example from the \package{fmt}
// Printf formats according to a format specifier and writes to standard
// output. It returns the number of bytes written and any write error
// encountered.
func Printf(format string, a ...interface{}) (n int, err error)
\section{Testing packages}
In Go it is customary to write (unit) tests for your package. Writing
tests involves the \package{testing} package and the program
\first{\prog{go test}}{tooling!go!test}. Both
have excellent documentation. When you include tests with your package
keep in mind that they have to build using the standard \file{Makefile}
(see section ``\titleref{sec:building a package}'').
%% CLEANFILES+=hello fib chain run.out
The testing itself is carried out with \prog{go test}.
The \prog{go test} program runs all the test functions. Without any
defined tests for our \package{even} package, \prog{go test} yields:
\pr \user{go test}
? even [no test files]
Let us fix this by defining a test in a test file. Test files reside
in the package directory and are named \file{*\_test.go}. Those test
files are just like other Go programs, but \prog{go test} will only
execute the test functions.
Each test function has the same signature and its name should start
with \lstinline{Test}:
func TestXxx(t *testing.T) |\coderemark{Test<Capital>restOftheName}|
When writing test you will need to tell \prog{go test} that a test has
failed or was successful. A successful test function just returns. When
the test fails you can signal this with the following
functions \cite{go_doc}. These are the most important ones (see \prog{go doc testing}
for more):
func (t *T) Fail()
\func{Fail} marks the test function as having failed but continues execution.
func (t *T) FailNow()
\func{FailNow} marks the test function as having failed and stops its execution.
Execution will continue at the next test. So any other test in
\emph{this} file are skipped too.
func (t *T) Log(args ...interface{})
\func{Log} formats its arguments using default formatting, analogous to
\func{Print()}, and records the text in the error log.
func (t *T) Fatal(args ...interface{})
\func{Fatal} is equivalent to \func{Log()} followed by \func{FailNow()}.
Putting all this together we can write our test. First
we pick a name: \file{even\_test.go}. Then we add the following contents:
\lstinputlisting[label=src:eventest,caption=Test file for even
Note that we use \lstinline{package even} on line 1, the tests fall in the same
namespace as the package we are testing. This not only convenient, but
also allows tests of unexported function and structures. We then import
the \package{testing} package and on line 5 we define the only test
function in this file. The displayed Go code should not hold any
surprises: we check if the \func{Even} function works OK.
Now, the moment we've been waiting for, executing the test:
\pr \user{go test}
ok even 0.001s
\noindent{}Our test ran and reported \texttt{ok}. Success!
To show how a failed test looks we redefine our test function:
// Entering the twilight zone
func TestEven(t *testing.T) {
if Even(2) {
t.Log("2 should be odd!")
We now get:
FAIL even 0.004s
--- FAIL: TestEven (0.00 seconds)
\qquad\qquad2 should be odd!
\noindent{}And you can act accordingly (by fixing the test for instance).
Writing new packages should go hand in hand with writing (some)
documentation and test functions. It will make your code better and it
shows that you really put in the effort.
\section{Useful packages}
The standard Go repository includes a huge number of packages and it is
even possible to install more along side your current Go installation.
It is very enlightening to browse the \file{\$GOROOT/src/pkg} directory and
look at the packages.
We cannot comment on each package, but the following are worth a mention:
\footnote{The descriptions are copied from the packages' \prog{go doc}. Extra
remarks are type set in italic.}
Package \package{fmt} implements formatted I/O with functions analogous
to C's \func{printf} and \func{scanf}. The format verbs are derived
from C's but are simpler. Some verbs (\%-sequences) that can be used:
\item[\%v]{The value in a default format.
when printing structs, the plus flag (\%+v) adds field names;}
\item[\%\#v]{a Go-syntax representation of the value.}
\item[\%T]{a Go-syntax representation of the type of the value;}
This package provides basic interfaces to I/O primitives.
Its primary job is to wrap existing implementations of such primitives,
such as those in package os, into shared public interfaces that
abstract the functionality, plus some other related primitives.
This package implements buffered I/O. It wraps an
object, creating another object (Reader or Writer) that also implements
the interface but provides buffering and some help for textual I/O.
The \package{sort} package provides primitives for sorting arrays
and user-defined collections.
The \package{strconv} package implements conversions to and from
string representations of basic data types.
The \package{os} package provides a platform-independent interface to operating
system functionality. The design is Unix-like.
The package \package{sync} provides basic synchronization primitives such as mutual
exclusion locks.
The \package{flag} package implements command-line flag parsing.
\emph{See ``\titleref{sec:option parsing}''
on page \pageref{sec:option parsing}.}
The \package{encoding/json} package implements encoding and decoding of JSON objects as
defined in RFC 4627 \cite{RFC4627}.
Data-driven templates for generating textual output such as HTML.
Templates are executed by applying them to a data structure. Annotations in
the template refer to elements of the data structure (typically a field of a
struct or a key in a map) to control execution and derive values to be
displayed. The template walks the structure as it executes and the ``cursor'' @
represents the value at the current location in the structure.
The \package{net/http} package implements parsing of HTTP requests, replies,
and URLs and provides an extensible HTTP server and a basic
HTTP client.
The \package{unsafe} package contains operations that step around the type safety of Go programs.
\emph{Normally you don't need this package.}
The \package{reflect} package implements run-time reflection, allowing a program to
manipulate objects with arbitrary types. The typical use is to take a
value with static type \lstinline|interface{}| and extract its dynamic type
information by calling \func{TypeOf}, which returns an object with interface
type \type{Type}.
\emph{See chapter \ref{chap:interfaces},
section ``\titleref{sec:introspection and reflection}''}.
The \package{os/exec} package runs external commands.
Jump to Line
Something went wrong with that request. Please try again.