A Go program is built by linking packages. A package is one or more source files
that declare constants, types, variables and functions, and that can all see one another’s
declarations (spec: Packages). The language describes packages and their initialisation.
Modules, versions and the layout of a project belong to the go command.
For the syntax of the package clause and imports, see
File structure.
Programs
A complete program links a single, unimported package named the main package with
all the packages it imports, transitively. The main package must have the package name
main and declare func main(), with no arguments and no result.
Execution initialises the program and then calls main. When that call returns,
the program exits. It does not wait for other goroutines (spec: Program execution).
Initialisation
Package initialisation
Within a package, package-level variables are initialised stepwise. Each step takes the variable that is earliest in declaration order and has no dependencies on uninitialised variables. Variables left over at the end form initialisation cycles, and the program is invalid (spec: Package initialization).
- Several variables initialised by one multi-valued expression are initialised together.
- Blank variables are treated like any others.
- The order across files is the order the files are presented to the compiler. Build
systems are encouraged to use lexical file name order; the
gocommand does. - Dependencies are found by lexical references to variables, functions and non-interface methods, analysed transitively within the package. Hidden dependencies, such as through an interface method call, are not seen.
var (
a = c + b // == 9
b = f() // == 4
c = f() // == 5
d = 3 // == 5 after initialisation has finished
)
func f() int {
d++
return d
}
// The initialisation order is d, b, c, a.
Then all init functions in the package run, in the order they appear in the
source, across files in the order given to the compiler. A package may have any number
of init functions, even several in one file. Each takes no arguments and
returns nothing, and none can be referred to from code.
Program initialisation
Packages are initialised one at a time, each only once, and imports before importers.
Since Go 1.21 the order is exact: given all packages sorted by import path, each step
initialises the first uninitialised package in the list whose imports are all initialised
(spec: Program initialization). Initialisation runs in a single goroutine, sequentially,
although an init function may start other goroutines.
Internal directories
Code in or below a directory named internal is importable only by code in the
directory tree rooted at the parent of internal. For example,
example.com/mod/a/internal/b can be imported by
example.com/mod/a/c but not by example.com/mod/d. The
go command enforces this. The language itself knows nothing of it.
Modules
A module is a tree of packages that are versioned together, defined by a
go.mod file at its root. Modules were added in Go 1.11 as an alternative to
GOPATH, and are the normal way of working.
module example.com/mod
go 1.26.0
toolchain go1.27.0
require (
golang.org/x/net v1.2.3
golang.org/x/text v1.5.0 // indirect
)
exclude golang.org/x/net v1.2.4
replace golang.org/x/net v1.2.3 => ./fork/net
retract [v1.0.0, v1.9.9]
tool golang.org/x/tools/cmd/stringer
go.mod file| Directive | Meaning |
|---|---|
module | The module’s path. Exactly one is required. A // Deprecated: comment marks the module as deprecated |
go | The minimum Go version required. At most one. See below |
toolchain | A suggested toolchain, used only when the module is the main module and the default toolchain is older |
godebug | A GODEBUG setting applied when the module is the main module |
require | The minimum version of a dependency. // indirect marks one not imported directly by the main module |
exclude | Prevents a version from being loaded. Applies only in the main module’s file |
replace | Replaces a module version with one found elsewhere, on disk or under another path. Applies only in the main module’s file |
retract | Marks a version or range of this module as not to be used |
tool | Adds a package as a dependency for use as a tool (Go 1.24) |
ignore | Directories the go command should skip when matching package patterns |
Module paths and major versions
A module path names the module and is the prefix of its packages’ import paths. A path
must not begin or end with a slash, and its elements use ASCII letters, digits and
-, ., _ and ~. A path element may not
begin or end with a dot.
- Versions follow semantic versioning, written with a
v:v1.2.3. - A module released at major version 2 or higher must end its path with a suffix such as
/v2. The suffix is not allowed atv0orv1. - Paths beginning with
gopkg.in/always carry a suffix with a dot, as ingopkg.in/yaml.v2.
The go directive
The go directive says which semantics a module was written for. The compiler
rejects language features newer than that version, in packages of the module, and a file
may also set its own version with a
build constraint. If the
directive is missing, go 1.16 is assumed.
- Since Go 1.21 the
goline is a strict minimum: toolchains refuse to use a module that declares a newer Go version. Thegocommand can find or download a suitable toolchain automatically. - At
go 1.21or later, a module’sgoline must be at least that of all its dependencies. - At
go 1.17or later, ago.modfile lists every module that provides a transitively imported package, which lets the module graph be pruned. - The
goline also selects the defaults for behaviour controlled byGODEBUG.
go.sum
A go.sum file beside go.mod holds cryptographic hashes of the
module’s direct and indirect dependencies. Each line has a module path, a version (ending
in /go.mod when the hash covers only the go.mod file) and a hash,
such as h1: followed by base64. h1, SHA-256, is currently the only
supported algorithm.
Downloaded modules are kept in the module cache, by default in
$GOPATH/pkg/mod, or under GOMODCACHE if that is set.
Vendoring
go mod vendor builds a folder named vendor in the main module’s
root containing copies of all the packages needed to build and test the main module’s
packages, not including test code of vendored packages. It also writes
vendor/modules.txt, which lists the vendored packages and the module versions
they came from. The go command reports an error if go.mod has
changed since that file was made.
If the module’s go version is 1.14 or higher and a vendor folder
exists, the go command behaves as if -mod=vendor were given.
Otherwise it acts as if -mod=readonly were given. Vendor folders in other places
than the main module root are ignored.
Workspaces
A go.work file defines a workspace of several modules, so they can be built
together without replace directives. It has go,
toolchain, godebug, use and replace
directives; use ./mymod adds a module on disk. A go directive is
required. The go command looks for the file in the current directory and its
parents, unless GOWORK is set to off.