Go Modules and Packages
Go programs are organized into packages. Your project uses go modules. Also, your project is a module. Each thing your program installs is a module, but what you actually use in your code is a package of the module. A repository contains one or more modules
repository
module
package
Note: go does, indeed, make itself aware of if it is indeed inside a git repository.
Modules
Firstly, initialize your project as a module.
go mod init my-project.com/some-go-service
Similar to Java projects, the example.com
part is your package namespace. If it’s actually published there is not important, it’s just an identifier. This will create a file go.mod
. Don’t really need to touch this file.
After that’s taken care of, you want to install some external dependencies.
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
// write go code here
After writing this in the entry point of your application, you can install the packages like this:
go install
This will install the dependencies and put them in your gopath. It will also create a go.sum
file. Ignore that file.
Note: you can also run go get .
. This command will also run go install
, but does a few more things, like building from source. Explanation(s) here.
Using remote modules is pretty much the same — use a URL of a package on github. This is how go works.
Also, try using go mod tidy
to pull in any missing dependencies, or cleanup any unused dependencies.
Import Paths
An import path is a string used to import a package, not a module. A packages import path is module path + package subdirectory path.
Packages in the go standard library do not have a module path prefix, just package.
Making Modules
To export a function or type from a module, it needs to be uppercase.
package handler
import "fmt"
func Handler() {
fmt.Println("Hello, world.")
}
The first statement in a Go source file must be package name. Executable commands must always use package main.
Packages
Inside of a module, you have packages. In newer versions of Go, it’s generally expected by the go tool that you will have a module initialized when you create a package. You might even get a compiler error when trying to execute a function in a package that is not enclosed in a module.
Somewhat similar to java, Go also has “package scope”. Functions in the same package are all accessible to eachother, regardless of if they are in the same file or not. However, as mentioned above, only capitalized functions in a package are exported and useable/importable elsewhere outside of the package.
Constants declared in any file in a package are also available to other files in the same package. As a matter of convention, you can generally view a Go file like this:
// comment about the package
package packagename // declaration of package
/*
START: package scope stuff
*/
import (
"crypto/sha256"
"fmt"
)
const name string = "Hello Package"
const pi float64 = 3.141
func getTheHash(s string) [32]byte {
return sha256.Sum256([]byte(name))
}
/*
END: package scope stuff
*/
func PackageName() {
hash := getTheHash(name)
fmt.Printf("The name of the package is: %x,\n The value of pi is %d\n The hash is: %x", name, pi, hash)
}
In this example, all of the constants and imports declared before the first function declaration are available inside the package. Import statements actually only need to be in one file in the package, but by convention are usually repeated in all files in a package.
Both getTheHash
and PackageName
are available in the package scope, but PackageName
is exported.