Table of contents

Go: package import and module management

Go: package import and module management

In go you can consider a package as all the files contained in a directory and a module as a collection of packages. To use the code of a package we need to import it, however, in Go there are no relative module imports. Before Go 1.8, to import packages (there were no modules) it was necessary to use the absolute path, considering as base the path pointed to by the environment variable $GOPATH or. Since Go 1.11, the easiest way to work with packages is to use go mod. I will explain the latter.

Differences between modules and packages in go

Difference between modules and packages in go

Defining the name of a package in Go

Before we start, do you remember that I told you in the introduction to the Go programming language, that the name of each package is set at the beginning of each file, placing it after the reserved word package?

For this example the package name will be videogame.

Once defined, I will create a model or struct in videogame.go.

//videogame/videogame.go
package videogame

type Videogame struct {
    Id int32
    Title string
}

Remember that the struct privacy rules say that in order for us to access a struct or its properties, from another package to where it was declared, we must use uppercase.

Once created, we will end up with a structure similar to this one

Project file structure, a folder called videogame, with a file of the same name inside

Localization of the main file and our module in go

Import packages with go.mod

What is a go.mod file for?

A go.mod file **defines a module and allows us to set the directory that we will use as a base to import the packages **.

go.mod file in the root of the project

go.mod file containing the module name

In the above example the go.mod file will allow us to treat the videogame path as a package and import code from the mimodulo/videogame path.

What does a go.mod file contain?

The basic go.mod file is very short, it only specifies the name of the module, which we will use to perform the imports, and the version of go. That’s all.

module mimodulo

go 1.15

Create a go.mod file

The go mod init command, followed by the name it will take as the base path for our package, will create a file named go.mod in the directory where we run it.

go mod init mimodulo

For example, if we name it mimodulo, all the folders that are at the same level as the go.mod file and that declare a package at the beginning of their file, will be considered packages.

Multiple directories to import as packages with go.mod

And we can import them directly from our main.go file.

import (
    "mimodulo/foobar"
    "mimodulo/videogame"
)

Remote modules in Go

The go module handler

Go has a module handler equivalent to pip and npm, python and javascript, respectively, called get.

go get

To get remote modules we run the go get command in console followed by the path to our package; it supports any repository, not just github. Since go version 1.18, go get does not compile the code it downloads, but just adds, updates or removes dependencies in the go.mod file.

go get github.com/labstack/echo

After executing the command, go will download the files to the path pointed to by the $GOPATH environment variable and perform the corresponding imports into your go.mod file.

module mipaquete

go 1.15

require (
    github.com/labstack/echo v3.3.10+incompatible // indirect
    github.com/labstack/gommon v0.3.1 // indirect
)

You will notice that their packages will be available for us to import with their respective path.

import "github.com/labstack/echo"

In case we need a specific version we declare it after the route.

go get github.com/labstack/echo/v4

go install

On the other hand, go install does not download code, but compiles a module and installs the binary into $GOPATH/bin, ignoring the contents of the go.mod file when a version is specified to it via the command line.

go install sigs.k8s.io/[email protected]

Go install will generally be used to install commands.

Import remote packages in go

Packages found in code repositories, such as GitHub, GitLab or BitBucket, require that we specify the full path to the repository as their import path.

go mod init github.com/usuario/paquete

Import packages without using them

There are times when we may want to import packages and not use them. For this, just add an underscore before the import.

import (
  _ "fmt"
)

Aliases when importing packages

Go also allows us to declare an alias when importing a package by prefixing the alias to the import path.

import nuestroAlias "ruta/a/paquete"

That way we can treat our alias as if it were the name of the package we are importing.

import nuestroAlias "mipaquete/videogame"
// ... nuestroAlias reemplaza a videogame
var vd = nuestroAlias.Videogame{Id: 1, Title: "hola"}

Imports with dot

Go allows direct access to the contents of the package if we import using a dot as alias. In this way we can ignore the package name and directly access the objects it contains.

import . "mipaquete/videogame"
// ... en lugar de videogame.Videogame podemos usar solo Videogame
var vd = Videogame{Id: 1, Title: "hola"}

Bookstores in Go

If you are looking for libraries to speed up the development of a project, there is a directory of frameworks, libraries and utilities at Awesome go, there are resources for everything from GUI, ORMs, web frameworks, machine learning and everything you can imagine.

Other resources

Eduardo Zepeda
Web developer and GNU/Linux enthusiast always learning something new. I believe in choosing the right tool for the job and that simplicity is the ultimate sophistication. I'm under the impression that being perfect is the enemy of getting things done. I also believe in the goodnesses of cryptocurrencies outside of monetary speculation.
Read more