How to Write Go Code - The Go Programming Language
How to Write Go Code - The Go Programming Language
Introduction
This document demonstrates the development of a simple Go package inside a module and
introduces the go tool, the standard way to fetch, build, and install Go modules, packages, and
commands.
Code organization
Go programs are organized into packages. A package is a collection of source files in the
same directory that are compiled together. Functions, types, variables, and constants defined
in one source file are visible to all other source files within the same package.
Note that you don't need to publish your code to a remote repository before you can build it. A
module can be defined locally without belonging to a repository. However, it's a good habit to
organize your code as if you will publish it someday.
Each module's path not only serves as an import path prefix for its packages, but also
indicates where the go command should look to download it. For example, in order to
download the module golang.org/x/tools, the go command would consult the repository
indicated by https://golang.org/x/tools (described more here).
An import path is a string used to import a package. A package's import path is its module path
joined with its subdirectory within the module. For example, the module
github.com/google/go-cmp contains a package in the directory cmp/. That package's
import path is github.com/google/go-cmp/cmp. Packages in the standard library do not
have a module path prefix.
go 1.16
$
The first statement in a Go source file must be package name. Executable commands must
always use package main.
Next, create a file named hello.go inside that directory containing the following Go code:
package main
import "fmt"
func main() {
fmt.Println("Hello, world.")
}
Now you can build and install that program with the go tool:
$ go install example/user/hello
$
This command builds the hello command, producing an executable binary. It then installs
that binary as $HOME/go/bin/hello (or, under Windows,
%USERPROFILE%\go\bin\hello.exe).
The install directory is controlled by the GOPATH and GOBIN environment variables. If GOBIN is
set, binaries are installed to that directory. If GOPATH is set, binaries are installed to the bin
subdirectory of the first directory in the GOPATH list. Otherwise, binaries are installed to the
bin subdirectory of the default GOPATH ($HOME/go or %USERPROFILE%\go).
You can use the go env command to portably set the default value for an environment
variable for future go commands:
$ go env -w GOBIN=/somewhere/else/bin
$
$ go env -u GOBIN
$
Commands like go install apply within the context of the module containing the current
working directory. If the working directory is not within the example/user/hello module, go
install may fail.
For convenience, go commands accept paths relative to the working directory, and default to
the package in the current working directory if no other path is given. So in our working
directory, the following commands are all equivalent:
$ go install example/user/hello
$ go install .
$ go install
Next, let's run the program to ensure it works. For added convenience, we'll add the install
directory to our PATH to make running binaries easy:
If you're using a source control system, now would be a good time to initialize a repository, add
the files, and commit your first change. Again, this step is optional: you do not need to use
source control to write Go code.
$ git init
Initialized empty Git repository in /home/user/hello/.git/
$ git add go.mod hello.go
$ git commit -m "initial commit"
[master (root-commit) 0b4507d] initial commit
1 file changed, 7 insertion(+)
create mode 100644 go.mod hello.go
$
The go command locates the repository containing a given module path by requesting a
corresponding HTTPS URL and reading metadata embedded in the HTML response (see go
help importpath). Many hosting services already provide that metadata for repositories
containing Go code, so the easiest way to make your module available for others to use is
usually to make its module path match the URL for the repository.
Let's write a morestrings package and use it from the hello program. First, create a
directory for the package named $HOME/hello/morestrings, and then a file named
reverse.go in that directory with the following contents:
Because our ReverseRunes function begins with an upper-case letter, it is exported, and can
be used in other packages that import our morestrings package.
$ cd $HOME/hello/morestrings
$ go build
$
This won't produce an output file. Instead it saves the compiled package in the local build
cache.
After confirming that the morestrings package builds, let's use it from the hello program.
To do so, modify your original $HOME/hello/hello.go to use the morestrings package:
package main
import (
"fmt"
"example/user/hello/morestrings"
)
func main() {
fmt.Println(morestrings.ReverseRunes("!oG ,olleH"))
}
Running the new version of the program, you should see a new, reversed message:
$ hello
Hello, Go!
An import path can describe how to obtain the package source code using a revision control
system such as Git or Mercurial. The go tool uses this property to automatically fetch
packages from remote repositories. For instance, to use github.com/google/go-cmp/cmp
in your program:
package main
import (
"fmt"
"example/user/hello/morestrings"
"github.com/google/go-cmp/cmp"
)
func main() {
fmt.Println(morestrings.ReverseRunes("!oG ,olleH"))
fmt.Println(cmp.Diff("Hello World", "Hello Go"))
}
Now that you have a dependency on an external module, you need to download that module
and record its version in your go.mod file. The go mod tidy command adds missing module
requirements for imported packages and removes requirements on modules that aren't used
anymore.
$ go mod tidy
go: finding module for package github.com/google/go-cmp/cmp
go: found github.com/google/go-cmp/cmp in github.com/google/go-cmp v0.5.4
$ go install example/user/hello
$ hello
Hello, Go!
string(
- "Hello World",
+ "Hello Go",
)
$ cat go.mod
module example/user/hello
go 1.16
$ go clean -modcache
$
Testing
Go has a lightweight test framework composed of the go test command and the testing
package.
You write a test by creating a file with a name ending in _test.go that contains functions
named TestXXX with signature func (t *testing.T). The test framework runs each such
function; if the function calls a failure function such as t.Error or t.Fail, the test is
considered to have failed.
package morestrings
import "testing"
$ cd $HOME/hello/morestrings
$ go test
PASS
ok example/user/hello/morestrings 0.165s
$
Run go help test and see the testing package documentation for more detail.
What's next
Subscribe to the golang-announce mailing list to be notified when a new stable version of Go
is released.
Visit the documentation page for a set of in-depth articles about the Go language and its
libraries and tools.
Getting help
For real-time help, ask the helpful gophers in the community-run gophers Slack server (grab
an invite here).