GOPATH and Module

GolangGolangBeginner
Practice Now

Introduction

GOPATH and Module are two different ways of managing dependencies in Go language. In this lab, we will introduce these two approaches.

Knowledge Points:

  • GOPATH
  • GOROOT
  • Module

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL go(("`Golang`")) -.-> go/DataTypesandStructuresGroup(["`Data Types and Structures`"]) go(("`Golang`")) -.-> go/FunctionsandControlFlowGroup(["`Functions and Control Flow`"]) go/DataTypesandStructuresGroup -.-> go/slices("`Slices`") go/FunctionsandControlFlowGroup -.-> go/functions("`Functions`") go/DataTypesandStructuresGroup -.-> go/strings("`Strings`") subgraph Lab Skills go/slices -.-> lab-149063{{"`GOPATH and Module`"}} go/functions -.-> lab-149063{{"`GOPATH and Module`"}} go/strings -.-> lab-149063{{"`GOPATH and Module`"}} end

Preparation

Enter the following commands in the terminal one by one:

cd ~/project
## Unzip to the current directory
tar -xzf helloWorld.tar.gz
## Check the target folder
ls helloWorld

Basic Module GOPATH

Before Go 1.11, we needed to set GOROOT and GOPATH when installing Go. GOROOT is the installation path of Go, which provides the Go language tools and standard library packages. GOPATH is the working directory for storing personal code.

Under GOPATH, there are three directories that serve different functions:

Directory Function
src repository for storing project source code
bin directory for storing compiled executables
pkg directory for storing compiled non-main packages

GOROOT is the installation path for Go tools and standard libraries, and its path is similar to GOPATH. For example, the fmt package used in the previous experiment is stored in the $GOROOT/src/fmt directory.

We can use the following commands to check the specific paths of GOPATH and GOROOT:

## Check the GOPATH directory
go env | grep GOPATH
## Check the GOROOT directory
go env | grep GOROOT

Introduction to Go Modules

Module is a feature introduced by Go in version 1.11 and enabled by default in version 1.13. It mainly solves the following two problems:

  • Over-reliance on GOPATH

    In the previous code structure, to facilitate importing the corresponding packages, all code files needed to be saved in the GOPATH/src directory. However, with Modules, Go code can be stored in any location.

  • Version dependency issues

    In the basic GOPATH, if multiple projects need to depend on different versions of the same project, it will not work properly.

Initialize mod

Next, let's demonstrate the use of Modules. Create a new testHello directory as our project folder:

## Create a new directory
mkdir testHello
## Switch to the testHello directory
cd testHello
## Use go mod to initialize the project
go mod init testHello

The output is as follows:

go: creating new go.mod: module testHello

The format for initializing mod is as follows, where projectName is the name of the project:

go mod init projectName

The generated mod file module testHello indicates that the current package name is testHello.

Create a testHello.go in the testHello folder and enter the following content:

package main

import "fmt"

func main(){
    fmt.Println("hello, world")
}

At this point, we have completed the initialization of the testHello project using mod.

Importing other packages with mod

In the preparation section of the previous experiment, we downloaded the helloWorld and test folders, which were initialized using mod. They are divided into two packages, helloWorld and test. The test.go file in the test package imports the Say method from the helloWorld package.

The package structure of helloWorld and test is as follows:

helloWorld
├── go.mod
└── helloWorld.go
test
├── go.mod
└── test.go

By looking at the files, we can see that the contents of helloWorld/go.mod and testHello/go.mod are similar. They both declare the package name and the Go version.

Next, let's take a look at the contents of test/go.mod:

module test

go 1.15

require "helloWorld" v0.0.1
replace "helloWorld" = > "../helloWorld"

Compared to helloWorld/go.mod, it adds the require and replace parameters. replace replaces the helloWorld in the test package with the relative path ../helloWorld. require indicates that the test package needs the helloWorld package, with the version specified as v0.0.1. The following table is a summary of the mod parameters:

Parameter Description
module Specifies the package
require Specifies dependencies
replace Replaces dependencies
exclude Excludes dependencies

This allows us to refer to the Say function in the helloWorld package in the test package:

cd ~/project/test
go run test.go

The output is as follows:

hello, world

Importing Remote Packages

In Go, it is very easy to import remote packages. Now let's demonstrate. Create a directory named remoteModule, and in the remoteModule folder, create a file named remote.go and enter the following code:

package main

import (
    "github.com/labex-labs/golang-dev-code/chap02module"
)
func main(){
    chap02module.StringTobase64("miiy")
}

Visit to see the imported file:

package chap02module

import (
    "encoding/base64"
    "fmt"
)

// Output hello
func Hello() {
    fmt.Println("hello")
}

// Convert the input string to base64 encoding
func StringTobase64(inString string) {
    // Encode to base64
    encodedString := base64.StdEncoding.EncodeToString([]byte(inString))
    fmt.Printf("Original string: %s\n", inString)
    fmt.Printf("Base64 encoded: %s\n", encodedString)
}

The remote.go file calls the chap02module package in github.com/labex-labs/golang-dev-code/chap02module and uses the StringTobase64 function to convert the string to base64 encoding.

Run the remote.go file. First, initialize the remoteModule folder with mod:

cd ~/project/remoteModule
## The package name can be anything, here it is named remoteModule for consistency
go mod init remoteModule

Then use the go run command to run the file. Adding the -v parameter will show the execution log of the program:

go get github.com/labex-labs/golang-dev-code/chap02module
go run -v remote.go

The go run command first searches for the required package chap02module locally. If it is not found, it will be downloaded using the go get command and stored in the $GOPATH/pkg/mod directory (you can switch to this directory to check), and finally the program will be executed using the downloaded package.

Mini Test

Let's reinforce what we have learned. In the previous section, we learned that in the chap02module package, in addition to the StringTobase64 function, there is also a Hello function. Now we need to call the Hello function to output "hello".

Requirements:

  • Create a remote2.go file in the ~/project/remoteModule2 directory
  • Students need to output "hello" by referring to the Hello function in the chap02module package.
$ go run remote2.go
hello

Tips:

  • Create a new folder named remoteModule2
  • Use go mod init to initialize it
✨ Check Solution and Practice

Summary

Let's review what we have learned in this experiment:

  • The meaning of GOPATH and GOROOT directories
  • The characteristics of Module management
  • A simple demonstration of using modules

In this lab, we have learned about version dependencies in different Go periods. Currently, the official Go recommendation is to use Modules to manage projects. In the next experiment, we will learn about Package management in Go, including the definition, initialization, and importing of packages.

Other Golang Tutorials you may like