Installation
Download pkg and install by opening pkg file and following installation process.
Also see: Installing multiple Go versions
$ /usr/local/go/bin/go version
go version go1.15.6 darwin/amd64
Install Go Tools
See: https://github.com/golang/tools
$ go get -u golang.org/x/tools/...
Setting GOPATH and GOBIN
Add /usr/local/go/bin
to ~/.zshrc
or ~/.bashrc
. Also see: https://github.com/golang/go/wiki/SettingGOPATH
$ grep -q '^export PATH=/usr/local/go/bin:$PATH' ~/.zshrc || echo 'export PATH=/usr/local/go/bin:$PATH' >> ~/.zshrc
$ grep -q '^export GOPATH=~/go' ~/.zshrc || echo 'export GOPATH=~/go' >> ~/.zshrc
$ grep -q '^export GOBIN=$GOPATH/bin' ~/.zshrc || echo 'export GOBIN=$GOPATH/bin' >> ~/.zshrc
$ tail -n3 ~/.zshrc
export PATH=/usr/local/go/bin:$PATH
export GOPATH=~/go
export GOBIN=$GOPATH/bin
Open a new terminal window and check GOPATH and GOBIN
$ go version
go version go1.15.6 darwin/amd64
$ go env GOPATH
/Users/user/go
$ echo $GOPATH
/Users/user/go
$ echo $GOBIN
/Users/user/go/bin
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN="/Users/user/go/bin"
GOCACHE="/Users/user/Library/Caches/go-build"
GOENV="/Users/user/Library/Application Support/go/env"
...
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
...
go help
$ go help
Go is a tool for managing Go source code.
Usage:
go [arguments]
The commands are:
bug start a bug report
build compile packages and dependencies
clean remove object files and cached files
doc show documentation for package or symbol
env print Go environment information
fix update packages to use new APIs
fmt gofmt (reformat) package sources
generate generate Go files by processing source
get download and install packages and dependencies
install compile and install packages and dependencies
list list packages or modules
mod module maintenance
run compile and run Go program
test test packages
tool run specified go tool
version print Go version
vet report likely mistakes in packages
Use "go help " for more information about a command.
Additional help topics:
buildconstraint build constraints
buildmode build modes
c calling between Go and C
cache build and test caching
environment environment variables
filetype file types
go.mod the go.mod file
gopath GOPATH environment variable
gopath-get legacy GOPATH go get
goproxy module proxy protocol
importpath import path syntax
modules modules, module versions, and more
module-get module-aware go get
module-auth module authentication using go.sum
module-private module configuration for non-public modules
packages package lists and patterns
testflag testing flags
testfunc testing functions
Use "go help " for more information about that topic.
Package
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.
Module
A repository contains one or more modules. A MODULE is a collection of related Go packages that are released together. A Go repository typically contains only one module, located at the root of the repository. A file named go.mod
there declares the MODULE PATH: the import path prefix for all packages within the module.
The module contains the packages in the directory containing its go.mod
file as well as subdirectories of that directory, up to the next subdirectory containing another go.mod
file (if any).
A module is nothing but a directory containing Go packages. These can be distribution packages or executable packages.
A module can also be treated as a package that contains nested packages.
A module is also like a package that you can share with other people. Hence, it has to be a Git or any other VCS repository which we can be hosted on a code-sharing platform like Github. Hence, Go recommends
- A Go module must be a VCS repository or a VCS repository should contain a single Go module.
- A Go module should contain one or more packages
- A package should contain one or more
.go
files in a single directory.
Also see:
- Anatomy of Modules in Go – medium.com
- How to Write Go Code – golang.org
Import Path
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.
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.
GOPATH
The GOPATH environment variable lists places to look for Go code and used to resolve import statements.
See: https://github.com/campoy/go-tooling-workshop/blob/master/1-source-code/1-workspace/1-intro.md
GOPATH and Modules
When using modules, GOPATH is no longer used for resolving imports.
However, it is still used to store downloaded source code (in GOPATH/pkg/mod)
and compiled commands (in GOPATH/bin).
$ go help gopath
The Go path is used to resolve import statements.
It is implemented by and documented in the go/build package.
The GOPATH environment variable lists places to look for Go code.
On Unix, the value is a colon-separated string.
On Windows, the value is a semicolon-separated string.
On Plan 9, the value is a list.
If the environment variable is unset, GOPATH defaults
to a subdirectory named "go" in the user's home directory
($HOME/go on Unix, %USERPROFILE%\go on Windows),
unless that directory holds a Go distribution.
Run "go env GOPATH" to see the current GOPATH.
See https://golang.org/wiki/SettingGOPATH to set a custom GOPATH.
Each directory listed in GOPATH must have a prescribed structure:
The src directory holds source code. The path below src
determines the import path or executable name.
The pkg directory holds installed package objects.
As in the Go tree, each target operating system and
architecture pair has its own subdirectory of pkg
(pkg/GOOS_GOARCH).
If DIR is a directory listed in the GOPATH, a package with
source in DIR/src/foo/bar can be imported as "foo/bar" and
has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a".
The bin directory holds compiled commands.
Each command is named for its source directory, but only
the final element, not the entire path. That is, the
command with source in DIR/src/foo/quux is installed into
DIR/bin/quux, not DIR/bin/foo/quux. The "foo/" prefix is stripped
so that you can add DIR/bin to your PATH to get at the
installed commands. If the GOBIN environment variable is
set, commands are installed to the directory it names instead
of DIR/bin. GOBIN must be an absolute path.
Here's an example directory layout:
GOPATH=/home/user/go
/home/user/go/
src/
foo/
bar/ (go code in package bar)
x.go
quux/ (go code in package main)
y.go
bin/
quux (installed command)
pkg/
linux_amd64/
foo/
bar.a (installed package object)
Go searches each directory listed in GOPATH to find source code,
but new packages are always downloaded into the first directory
in the list.
See https://golang.org/doc/code.html for an example.
GOPATH and Modules
When using modules, GOPATH is no longer used for resolving imports.
However, it is still used to store downloaded source code (in GOPATH/pkg/mod)
and compiled commands (in GOPATH/bin).
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".
Here's an extended version of the directory layout above:
/home/user/go/
src/
crash/
bang/ (go code in package bang)
b.go
foo/ (go code in package foo)
f.go
bar/ (go code in package bar)
x.go
internal/
baz/ (go code in package baz)
z.go
quux/ (go code in package main)
y.go
The code in z.go is imported as "foo/internal/baz", but that
import statement can only appear in source files in the subtree
rooted at foo. The source files foo/f.go, foo/bar/x.go, and
foo/quux/y.go can all import "foo/internal/baz", but the source file
crash/bang/b.go cannot.
See https://golang.org/s/go14internal for details.
Vendor Directories
Go 1.6 includes support for using local copies of external dependencies
to satisfy imports of those dependencies, often referred to as vendoring.
Code below a directory named "vendor" is importable only
by code in the directory tree rooted at the parent of "vendor",
and only using an import path that omits the prefix up to and
including the vendor element.
Here's the example from the previous section,
but with the "internal" directory renamed to "vendor"
and a new foo/vendor/crash/bang directory added:
/home/user/go/
src/
crash/
bang/ (go code in package bang)
b.go
foo/ (go code in package foo)
f.go
bar/ (go code in package bar)
x.go
vendor/
crash/
bang/ (go code in package bang)
b.go
baz/ (go code in package baz)
z.go
quux/ (go code in package main)
y.go
The same visibility rules apply as for internal, but the code
in z.go is imported as "baz", not as "foo/vendor/baz".
Code in vendor directories deeper in the source tree shadows
code in higher directories. Within the subtree rooted at foo, an import
of "crash/bang" resolves to "foo/vendor/crash/bang", not the
top-level "crash/bang".
Code in vendor directories is not subject to import path
checking (see 'go help importpath').
When 'go get' checks out or updates a git repository, it now also
updates submodules.
Vendor directories do not affect the placement of new repositories
being checked out for the first time by 'go get': those are always
placed in the main GOPATH, never in a vendor subtree.
See https://golang.org/s/go15vendor for details.
Intro
$ mkdir /tmp/hello
$ cd /tmp/hello
$ vi hello.go
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
- Declare a
main
package (a package is a way to group functions). - Import the popular
fmt
package, which contains functions for formatting text, including printing to the console. This package is one of the standard library packages you got when you installed Go. - Implement a
main
function to print a message to the console. Amain
function executes by default when you run code in the file.
$ go run hello.go
Hello, World!
go run hello
is different from go run hello.go
. See go help run
.
$ go run hello
package hello is not in GOROOT (/usr/local/go/src/hello)
package main
import "fmt"
import "rsc.io/quote"
func main() {
fmt.Println(quote.Go())
}
$ go run hello2.go
hello2.go:5:8: cannot find package "rsc.io/quote" in any of:
/usr/local/go/src/rsc.io/quote (from $GOROOT)
/Users/aung/go/src/rsc.io/quote (from $GOPATH)
Put your own code in a module for tracking dependencies.
When your code imports packages from another module, a go.mod file lists the specific modules and versions providing those packages. That file stays with your code, including in your source code repository.
To create a go.mod file, run the go mod init
command, giving it the name of the module your code will be in (here, just use “hello”):
$ go mod init hello2
go: creating new go.mod: module hello2
$ cat go.mod
module hello2
go 1.15
$ go run hello2
go: finding module for package rsc.io/quote
go: downloading rsc.io/quote v1.5.2
go: found rsc.io/quote in rsc.io/quote v1.5.2
go: downloading rsc.io/sampler v1.3.0
go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
# hello2
./hello2.go:7:6: main redeclared in this block
previous declaration at ./hello.go:5:6
Remove the entire module download cache, including unpacked source code of versioned dependencies.
$ go clean -modcache
$ go run hello2.go
go: downloading rsc.io/quote v1.5.2
go: downloading rsc.io/sampler v1.3.0
go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
Don't communicate by sharing memory, share memory by communicating.
But before it ran the code, go run
located and downloaded the rsc.io/quote
module that contains the package you imported if not exists in cache. By default, it downloaded the latest version — v1.5.2. Go build commands are designed to locate the modules required for packages you import.
$ go run hello2.go
Don't communicate by sharing memory, share memory by communicating.
Module dependencies are automatically downloaded to the pkg/mod
subdirectory of the directory indicated by the GOPATH
environment variable. The downloaded contents for a given version of a module are shared among all other modules that require
that version, so the go
command marks those files and directories as read-only. To remove all downloaded modules, you can pass the -modcache
flag to go clean
:
$ tree --dirsfirst -FL 3 ~/go/pkg
/Users/user/go/pkg
|-- mod/
| |-- cache/
| | `-- download/
| |-- golang.org/
| | `-- x/
| `-- rsc.io/
| |-- quote@v1.5.2/
| `-- sampler@v1.3.0/
`-- sumdb/
`-- sum.golang.org/
`-- latest
go list
– List package or modules
$ go list
hello2
$ ls
go.mod go.sum hello.go hello2.go
$ cat go.sum
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
go list all
– lists all the packages on the local system.
$ go list all
archive/zip
...
errors
flag
fmt
go/ast
go/build
go/doc
go/format
...
hello2
...
go list std
– “std” is like “all” but expands to just the packages in the standard Go library
Also See:
$ go help gopath
$ go help packages
$ go help importpath
$ go help packages
Many commands apply to a set of packages:
go action [packages]
Usually, [packages] is a list of import paths.
An import path that is a rooted path or that begins with
a . or .. element is interpreted as a file system path and
denotes the package in that directory.
Otherwise, the import path P denotes the package found in
the directory DIR/src/P for some DIR listed in the GOPATH
environment variable (For more details see: 'go help gopath').
...
If no import paths are given, the action applies to the
package in the current directory.
There are four reserved names for paths that should not be used
for packages to be built with the go tool:
- "main" denotes the top-level package in a stand-alone executable.
- "all" expands to all packages found in all the GOPATH
trees. For example, 'go list all' lists all the packages on the local
system. When using modules, "all" expands to all packages in
the main module and their dependencies, including dependencies
needed by tests of any of those.
- "std" is like all but expands to just the packages in the standard
Go library.
- "cmd" expands to the Go repository's commands and their
internal libraries.
...
$ go help importpath
An import path (see 'go help packages') denotes a package stored in the local
file system. In general, an import path denotes either a standard package (such
as "unicode/utf8") or a package found in one of the work spaces (For more
details see: 'go help gopath').
Relative import paths
An import path beginning with ./ or ../ is called a relative path.
The toolchain supports relative import paths as a shortcut in two ways.
First, a relative path can be used as a shorthand on the command line.
If you are working in the directory containing the code imported as
"unicode" and want to run the tests for "unicode/utf8", you can type
"go test ./utf8" instead of needing to specify the full path.
Similarly, in the reverse situation, "go test .." will test "unicode" from
the "unicode/utf8" directory. Relative patterns are also allowed, like
"go test ./..." to test all subdirectories. See 'go help packages' for details
on the pattern syntax.
Second, if you are compiling a Go program not in a work space,
you can use a relative path in an import statement in that program
to refer to nearby code also not in a work space.
This makes it easy to experiment with small multipackage programs
outside of the usual work spaces, but such programs cannot be
installed with "go install" (there is no work space in which to install them),
so they are rebuilt from scratch each time they are built.
To avoid ambiguity, Go programs cannot use relative import paths
within a work space.
Remote import paths
Certain import paths also
describe how to obtain the source code for the package using
a revision control system.
A few common code hosting sites have special syntax:
Bitbucket (Git, Mercurial)
import "bitbucket.org/user/project"
import "bitbucket.org/user/project/sub/directory"
GitHub (Git)
import "github.com/user/project"
import "github.com/user/project/sub/directory"
Launchpad (Bazaar)
import "launchpad.net/project"
import "launchpad.net/project/series"
import "launchpad.net/project/series/sub/directory"
import "launchpad.net/~user/project/branch"
import "launchpad.net/~user/project/branch/sub/directory"
IBM DevOps Services (Git)
import "hub.jazz.net/git/user/project"
import "hub.jazz.net/git/user/project/sub/directory"
For code hosted on other servers, import paths may either be qualified
with the version control type, or the go tool can dynamically fetch
the import path over https/http and discover where the code resides
from a tag in the HTML.
To declare the code location, an import path of the form
repository.vcs/path
specifies the given repository, with or without the .vcs suffix,
using the named version control system, and then the path inside
that repository. The supported version control systems are:
Bazaar .bzr
Fossil .fossil
Git .git
Mercurial .hg
Subversion .svn
For example,
import "example.org/user/foo.hg"
denotes the root directory of the Mercurial repository at
example.org/user/foo or foo.hg, and
import "example.org/repo.git/foo/bar"
denotes the foo/bar directory of the Git repository at
example.org/repo or repo.git.
When a version control system supports multiple protocols,
each is tried in turn when downloading. For example, a Git
download tries https://, then git+ssh://.
By default, downloads are restricted to known secure protocols
(e.g. https, ssh). To override this setting for Git downloads, the
GIT_ALLOW_PROTOCOL environment variable can be set (For more details see:
'go help environment').
If the import path is not a known code hosting site and also lacks a
version control qualifier, the go tool attempts to fetch the import
over https/http and looks for a tag in the document's HTML
.
The meta tag has the form:
The import-prefix is the import path corresponding to the repository
root. It must be a prefix or an exact match of the package being
fetched with "go get". If it's not an exact match, another http
request is made at the prefix to verify the tags match.
The meta tag should appear as early in the file as possible.
In particular, it should appear before any raw JavaScript or CSS,
to avoid confusing the go command's restricted parser.
The vcs is one of "bzr", "fossil", "git", "hg", "svn".
The repo-root is the root of the version control system
containing a scheme and not containing a .vcs qualifier.
For example,
import "example.org/pkg/foo"
will result in the following requests:
https://example.org/pkg/foo?go-get=1 (preferred)
http://example.org/pkg/foo?go-get=1 (fallback, only with -insecure)
If that page contains the meta tag
the go tool will verify that https://example.org/?go-get=1 contains the
same meta tag and then git clone https://code.org/r/p/exproj into
GOPATH/src/example.org.
When using GOPATH, downloaded packages are written to the first directory
listed in the GOPATH environment variable.
(See 'go help gopath-get' and 'go help gopath'.)
When using modules, downloaded packages are stored in the module cache.
(See 'go help module-get' and 'go help goproxy'.)
When using modules, an additional variant of the go-import meta tag is
recognized and is preferred over those listing version control systems.
That variant uses "mod" as the vcs in the content value, as in:
This tag means to fetch modules with paths beginning with example.org
from the module proxy available at the URL https://code.org/moduleproxy.
See 'go help goproxy' for details about the proxy protocol.
Import path checking
When the custom import path feature described above redirects to a
known code hosting site, each of the resulting packages has two possible
import paths, using the custom domain or the known hosting site.
A package statement is said to have an "import comment" if it is immediately
followed (before the next newline) by a comment of one of these two forms:
package math // import "path"
package math /* import "path" */
The go command will refuse to install a package with an import comment
unless it is being referred to by that import path. In this way, import comments
let package authors make sure the custom import path is used and not a
direct path to the underlying code hosting site.
Import path checking is disabled for code found within vendor trees.
This makes it possible to copy code into alternate locations in vendor trees
without needing to update import comments.
Import path checking is also disabled when using modules.
Import path comments are obsoleted by the go.mod file's module statement.
See https://golang.org/s/go14customimport for details.