Javascript required
Skip to content Skip to sidebar Skip to footer

Engageny Inside Out and Back Again Module 1

Larn what has changed in Go i.16

Photo past Toby Stodart on Unsplash

If you work with Get, you bargain with packages and modules all the time. In Go, a package is a directory of .go files, and packages form the basic building blocks of a Become program. Using packages, you lot organize your lawmaking into reusable units.

A module , on the other hand, is a collection of Get packages, with dependencies and versioning built-in. Modules were first introduced in Go 1.11, only information technology wasn't until Go 1.16 that the go command builds packages in module-aware manner past default. This has acquired quite a bit of confusion for Go developers when using local and third-political party packages. This article attempts to clarify the situation and I promise the examples in this article volition make it crystal clear.

Get Surroundings Variables

Before we dive into the topic of packages and modules, you need to sympathise Go surroundings variables. Go uses environment variables every bit the machinery for configuring the paths of libraries and packages. To view the various surround set by Go, use the go env command:

          $            go env
GO111MODULE="automobile"

GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/weimenglee/Library/Caches/go-build"
GOENV="/Users/weimenglee/Library/Awarding Support/become/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/weimenglee/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/weimenglee/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,directly"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.16.2"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-one thousand -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-grand -O2"
CGO_LDFLAGS="-1000 -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/5z/b_k8j2vs2jg1kcp7yb7rs4vh0000gn/T/go-build3486438553=/tmp/become-build -gno-record-gcc-switches -fno-mutual"

In detail, three Go environment variables are worth mentioning (shown in assuming above):

  • GOROOT — specifies where your Get SDK is located.
  • GOPATH — specifies the root of your workspace (where your packages and dependencies are located).
  • GO111MODULE — specifies how Go imports your packages. It tin can assume the following three values: "on", "off", or "auto".

What is and then special about Become ane.eleven?

A picayune backgrounder is in order. Prior to Go 1.11, all Go projects must exist created inside the directory specified by the GOPATH environment variable. This GOPATH directory contains source code and binaries that your code depends on.

Starting from Get 1.11 (hence the environment variable named after it — GO111MODULE), your project can now reside exterior of the GOPATH directory. Become one.11 introduces the concept of modules. A module is a directory of packages with a file named become.mod at its root. The become.modern file defines the module's import path, also equally its specific dependencies (yous will see its use in the examples later in this article). With modules:

  • Go projects practise not demand to reside in GOPATH
  • Package management is greatly improved

Agreement GO111Module

In Go 1.15 and earlier, the default fashion for GO111MODULE is ready to "auto". This means that if a project directory (or whatever parent directory) contains a go.mod file, it will be treated equally a module. Else information technology will apply the legacy GOPATH mode (I will provide examples of this in the following sections).

In Go i.16, the module-aware mode is at present switched on (GO111MODULE=on) by default. So how does this affect the fashion you lot use 3rd party modules or write your ain modules? I will illustrate the various scenarios in the following sections.

GO111MODULE=on

Since this is the default manner in Become 1.sixteen, permit'southward start with this scenario first. I shall illustrate this using an example. Suppose you have a folder named HelloApp with a file named main.go:

          HelloApp
|___main.go

To switch the GO111MODULE to on, you can use the following commands: export GO111MODULE="on" (for macOS) or prepare GO111MODULE=on (for Windows)

The main.go file has the post-obit statements:

          parcel main          import (
"fmt"
"github.com/hackebrot/turtle"
)
func main() {
emoji, ok := turtle.Emojis["smiley"]
if !ok {
fmt.Println("No emoji found.")
} else {
fmt.Println(emoji.Char)
}
}

Using third-party packages

In this primary package, I am using a tertiary-political party package — github.com/hackebrot/turtle. And so I need to install information technology first:

          $            get install github.com/hackebrot/turtle@latest                  

Notice that you need to specify the version of the package to install. If yous want to use the latest version, use @latest.

Once the package is installed, you can find it in the GOPATH/pkg/mod directory. For case, my GOPATH is "/Users/weimenglee/get", then the module volition be installed in the "/Users/weimenglee/go/pkg/mod" directory:

When GO111MODULE=on, third-party packages will be stored in the GOPATH/pkg/modern/ directory

In Go 1.16, if your program uses a third-party package, you need to create a go.mod file starting time before yous can run it. And then the adjacent step would be to use the "go mod init" command:

          $            go mod init myapp
go: creating new go.mod: module myapp
get: to add together module requirements and sums:
go modernistic tidy

In the to a higher place instance, I used the module path name of myapp for my program. This proper noun would exist used as the import name of your module (when another program is trying to import your module).

Note that if you intend to publish this parcel (or module), this must be a path from which your module tin can be downloaded by Go tools. For example, if you desire to brand this parcel available on Github.com, and so yous should use a name like: github.com/yourname/myapp.

Once this step is done, you should now have a get.mod file in your electric current directory:

          HelloApp
|___main.go
|___go.modernistic

It should have the following content:

          module myapp          go 1.16        

Next, you lot demand to run the "go mod tidy" control:

          $            go mod tidy
become: finding module for package github.com/hackebrot/turtle
go: found github.com/hackebrot/turtle in github.com/hackebrot/turtle v0.one.0
go: finding module for package github.com/google/get-cmp/cmp
go: finding module for packet github.com/hackebrot/go-repr/repr
become: establish github.com/google/go-cmp/cmp in github.com/google/go-cmp v0.5.5
go: institute github.com/hackebrot/get-repr/repr in github.com/hackebrot/go-repr v0.ane.0

This command will examine the third-party packages you are using in your programme and add together them as dependencies into the get.mod file. Afterward running the above control, your get.mod file should now expect similar this:

          module myapp          go i.sixteen                      require (
github.com/google/go-cmp v0.5.v // indirect
github.com/hackebrot/get-repr v0.1.0 // indirect
github.com/hackebrot/turtle v0.1.0
)

Y'all should too accept another file named get.sum:

          HelloApp
|___main.go
|___go.mod
|___go.sum

The content of go.sum looks similar this:

          github.com/google/go-cmp v0.5.v h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=          github.com/google/get-cmp v0.5.five/go.modern h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=          github.com/hackebrot/go-repr v0.1.0 h1:28FyOiVx+rHPqEj/nqUbxqs2ocz2hfM9gP01kAeJJoA=          github.com/hackebrot/get-repr v0.ane.0/become.modernistic h1:5nbEBC4Y57U1dVAlQGF4lQdqAJZAwu7cszx8HtEq8XM=          github.com/hackebrot/turtle v0.1.0 h1:cmS72nZuooIARtgix6IRPvmw8r4u8olEZW02Q3DB8YQ=          github.com/hackebrot/turtle v0.one.0/go.mod h1:vDjX4rgnTSlvROhwGbE2GiB43F/50/8V5TXoRJL2cYTs=          golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.modernistic h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=        

The go.sum file contains the expected cryptographic checksums of the content of specific module versions that yous utilise in your program.

You lot can at present finally run your plan:

          $            become run main.become
😃

Using local packages

How about using packages that you define locally? Suppose now you have a folder named geometry within the HelloApp folder. Within the geometry folder you have another file named geometry.go:

          HelloApp
|___main.go
|___go.modernistic
|___go.sum
|___geometry
|___geometry.get

The content of geometry.go is every bit follows:

          package geometry
import (
"math"
)
type Signal struct {
10 float64
Y float64
}
func (p Signal) Length() float64 {
return math.Sqrt(math.Pow(p.10, 2.0) + math.Pow(p.Y, 2.0))
}

To make apply of the geometry package in the chief package file, you lot tin can now import it via "myapp/geometry" (call up that nosotros take earlier used the module import path name of "myapp"?):

          package main          import (
"fmt"
"myapp/geometry"
"github.com/hackebrot/turtle"
)
func main() {
emoji, ok := turtle.Emojis["smiley"]
if !ok {
fmt.Println("No emoji found.")
} else {
fmt.Println(emoji.Char)
}
pt1 := geometry.Point{X: 2, Y: iii}
fmt.Println(pt1)
fmt.Println(pt1.Length())
}

You tin can now simply run the program using the "get run main.get" command:

          $            get run chief.go
😃
{ii 3}
3.605551275463989

GO111MODULE=off

The next scenario we shall discuss at present is when GO111MODULE is turned off. To turn off module-style, apply the following command (for macOS):

          $            export GO111MODULE="off"                  

For Windows users, use the post-obit control:

                      ready GO111MODULE=off                  

Every bit usual, let'south start off with the HelloApp folder containing the main.go file:

          HelloApp
|___main.get

The content of principal.get is as follows:

          bundle main          import (
"fmt"
"github.com/hackebrot/turtle"
)
func master() {
emoji, ok := turtle.Emojis["smiley"]
if !ok {
fmt.Println("No emoji found.")
} else {
fmt.Println(emoji.Char)
}
}

Using third-party packages

When module-way is turned off, you cannot use the "go install" command; y'all tin can only use the "go go" control:

          $            go go github.com/hackebrot/turtle                  

Once the bundle is downloaded, you can now discover it in the GOPATH/src directory. For example, my GOPATH is "/Users/weimenglee/go", so the parcel volition be installed in the "/Users/weimenglee/go/src" directory:

When GO111MODULE=off, tertiary-party packages will exist stored in the GOPATH/src/ directory

To run the programme, use the "go run main.go" command:

          $            become run main.go
😃

Using local packages

When module-mode is turned off, all local packages that you create must exist stored in the GOROOT or GOPATH/src directories. Using the aforementioned geometry package that I have used before, you now need to create a folder named geometry in the GOROOT or GOPATH/src binder and add a file named geometry.become to it:

When GO111MODULE=off, all local packages must be stored in the GOROOT or GOPATH/src/ directories

To use the geometry parcel, you now need to import the "geometry" package in your main.go file (the import proper name of the parcel is based on its folder structure in the GOPATH/src/ folder):

          bundle main          import (
"fmt"
"geometry"
"github.com/hackebrot/turtle"
)
func master() {
emoji, ok := turtle.Emojis["smiley"]
if !ok {
fmt.Println("No emoji constitute.")
} else {
fmt.Println(emoji.Char)
}
pt1 := geometry.Bespeak{Ten: ii, Y: 3}
fmt.Println(pt1)
fmt.Println(pt1.Length())
}

You lot can now run the program using "become run master.go":

          $            get run main.go            
😃
{2 three}
3.605551275463989

GO111MODULE=auto

Finally, let's discuss what happens when you ready GO111MODULE to machine. When you set the GO111MODULE=auto, how your application looks for packages depends on whether you take a go.mod file in your projection folder.

If in that location is no go.modern file in your current project folder:

          HelloApp
|___main.go

And your primary.go contains the following:

          package main
import (
"fmt"
"github.com/hackebrot/turtle"
)
func main() {
emoji, ok := turtle.Emojis["smiley"]
if !ok {
fmt.Println("No emoji found.")
} else {
fmt.Println(emoji.Char)
}
}

You demand to manually download the third-party packages using the "become get" command, such as:

          $            go get github.com/hackebrot/turtle                  

The above command will download the third-party packet into the GOPATH/src directory. And you can at present run your program using "become run principal.become".

If there is a go.mod file in the current directory:

          HelloApp
|___main.go
|___go.mod

And the go.modern file contains the dependencies:

          module myapp          go 1.16          require (
github.com/google/go-cmp v0.5.5 // indirect
github.com/hackebrot/go-repr v0.1.0 // indirect
github.com/hackebrot/turtle v0.ane.0
)

When you try to run the master.go file using "become run main.go", Go will automatically install the required packages into the GOPATH/pkg/mod directory:

          $            go run main.become
😃

Then there is now no demand for you to use the "become install" control to download the third-party bundle. The 3rd party package will now be saved into the GOPATH/pkg/mod directory.

Using local packages

If at that place is no become.mod file in your project directory, your local package must exist located within the electric current directory:

          HelloApp
|___main.get
|___geometry
|___geometry.go

The following main.get file shows how the geometry package is imported and used:

          packet main          import (
"fmt"
"geometry"
"github.com/hackebrot/turtle"
)
func main() {
emoji, ok := turtle.Emojis["smiley"]
if !ok {
fmt.Println("No emoji found.")
} else {
fmt.Println(emoji.Char)
}
pt1 := geometry.Point{X: two, Y: three}
fmt.Println(pt1)
fmt.Println(pt1.Length())
}

If there is a get.modern file in your project directory, your local package(south) must all be stored in either your GOROOT or GOPATH/src directory. In my case, the GOROOT is pointing to the "/usr/local/get/src " folder and GOPATH is pointing to "/Users/weimenglee/go/". In the following example, I put the geometry folder in the "/usr/local/become/src " folder.

Putting the geometry folder in the GOROOT directory

Visual Studio Code

If you lot write your Go program using Visual Studio Code, chances are y'all use the VS Code Go extension.

Using the VS Code Get extension

When switching through the diverse module-aware modes, information technology is easy to cause confusion to the extension when it attempts to import your modules. If yous observe the extension flagging errors in your import statements but your program tin run anyway, you should Disable your VS Code Go extension, reload it, and then enable information technology over again.

Want to acquire Get? Cheque out my latest book on Go programming at Amazon.com.

Become Programming Linguistic communication For Dummies 1st Edition (Wei-Meng Lee)

bylespriuset90.blogspot.com

Source: https://levelup.gitconnected.com/using-modules-and-packages-in-go-36a418960556