Packages
Module
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.
- You can technically have multiple modules in one repository, but this is not recommended.
- You preferably want to keep one
module
per eachrepository
.
A moudle path
defined in the go.mod
file declares the import path prefix
for all packages
within the module.
Module
is a collection of Gopackages
.module
is the way toimport
andexport
Go files to external scopes.
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.
package
is a directory of.go
files.package
is scoped within amodule
.
project-repository/ |-go.mod # module1, does not include module2 |-modname.go # package in module1, doesn't matter outside context of module1 |-modname_test.go # 1 mod per 1 repo project-repo-2/ |-module2 # module2 |-go.mod # uses package1 and package2 |-package1 # reusable within module2 |-funcs.go |-package2 # reusable within module2 |-variables.go
Package
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.
Package
vs Module
Packages
within the same module
can be imported by other packages
via a name path reference.
External packages are installed via a go get
command (imported as a module
).
Although module
defines how a code is versioned and which dependencies are included, you can only import
a package
of an imported module
.
import "github.com/module/package1" import "github.com/module/package2"
Import
You cannot import a file
in Go lang.
- You can only import
packages
within amodule
.
If you want to extract shared common variables out of a file that is consumed in multiple places, they must be declared in a separate package
(can't be a file path like Javascript).
One repository
= one module
.
- One
module
= manypackages
.
One directory
= one package
.
package
is what can be imported by other files.
get
go get
is used to reference and install an external package (module
).
go get github.com/some/module
Running the go get
command will install the target package/module and its dependencies (as defined in the go.mod
file of the target package/module).
In your current project mod
file, require()
method will list the dependencies and versions (automatically listed once compiled).
get
downloads thepackages
named by theimport paths
, along with their dependencies.
require ( github.com/some/module v0.14.0 // indirect )
You can update a package by getting it again.
go get -u example.com/some-module
Why are Go packages Github URLs?
The Go path ($GOPATH
) is used to resolve import
statements.
The statement import "github.com/stretchr/testify/assert"
doesn't mean that the package is directly imported from github website (through http).
It's imported from your local, from github.com/stretchr/testify
path under $GOPATH/src
. The package was downloaded and stored there before, so it can be imported into any project.
- Inital fetching of package would reference the Github URL.
alias
package import
import ( "text/template" // this is imported as htmltemplate to avoid collision htmltemplate "html/template" )
Go
Does Not Support Circular Dependencies
Do not import packages in tests
When the test is written for a same package method/type, you don't re-import or reference it via Package_Name.method
.
- Go has low tolerance for
circular dependencies
- Golang programs must be
acyclic
. - In Golang cyclic imports are not allowed
- That is its import graph must not contain any loops
- Golang programs must be
// foo.go package foo func Foo() {...} // foo_test.go package foo // try to access Foo() foo.Foo() // WRONG <== This was the issue. You are already in package foo, there is no need to use foo.Foo() to access Foo() Foo() // CORRECT