Johnny.sh

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.

Last modified: September 24, 2021
/about
/uses
/notes
/talks
/projects
/podcasts
/reading-list
/spotify
© 2023