Vai al contenuto
eLearner.app
Modulo 9 · Lezione 4 di 544/50 nel corso~12 min
Lezioni del modulo (4/5)

Go modules

Un modulo Go è un'unità versionabile composta da uno o più package. È la base del sistema di dipendenze moderno (Go 1.11+): niente più GOPATH, niente più vendor obbligatorio, dipendenze esplicite e riproducibili.

go.mod: il manifest del modulo

Code
module example.com/myapp

go 1.22

require (
    github.com/google/uuid v1.6.0
    golang.org/x/time     v0.5.0
)

Tre direttive principali:

  • module <path> — il path d'importazione del modulo. Tutti i package interni si importano come example.com/myapp/sub/pkg. Non è obbligato essere un URL reale, ma per pubblicare su go get deve risolvere.
  • go <version> — la versione minima di Go richiesta (anche per controllare quali feature del linguaggio sono ammesse, es. range-over-func in 1.23).
  • require — le dipendenze dirette con versione precisa.

Altre direttive: replace (sostituisce una dep con una fork o un path locale), exclude, retract.

go.sum: il lockfile crittografico

Affiancato a go.mod, go.sum contiene un hash crittografico di OGNI versione scaricata (incluse le dep transitive). Garantisce riproducibilità: se qualcuno tampera una versione pubblicata, il build fallisce.

Va sempre committato. Va aggiornato automaticamente dai comandi go.

Comandi essenziali

Bash
go mod init example.com/myapp        # crea go.mod
go get github.com/google/uuid        # aggiunge dep all'ultima versione
go get github.com/google/uuid@v1.5.0 # versione specifica
go get -u ./...                      # upgrade di tutte le dep
go mod tidy                          # rimuove deps non usate, aggiunge mancanti
go mod download                      # scarica tutto in cache
go mod why github.com/x/y            # spiega perché una dep è inclusa
go mod graph                         # grafo completo delle dipendenze

go mod tidy è quello che invochi dopo ogni modifica agli import: garantisce che go.mod rifletta esattamente i package effettivamente usati.

Semantic Import Versioning (SIV)

Le versioni seguono SemVer: v1.2.3 = MAJOR.MINOR.PATCH. La parte interessante è la major v2+:

  • Major v0 e v1 → path normale: github.com/foo/bar.
  • Major v2 o successive → il path include la versione major: github.com/foo/bar/v2.
Go
import "github.com/foo/bar/v2"

Questo permette di importare contemporaneamente v1 e v2 di una stessa libreria (utile durante migrazioni progressive).

Path d'import e package interni

Se il tuo modulo è example.com/myapp, una sub-cartella utils/ viene importata come:

Go
import "example.com/myapp/utils"

Il path dipende solo dal nome dichiarato in go.mod, non dalla posizione su disco: lo stesso codice in cartelle diverse continua a funzionare.

Workspace mode (Go 1.18+)

Per lavorare contemporaneamente su più moduli che si referenziano (es. una libreria e un'app che la usa):

Bash
go work init ./lib ./app

Crea go.work: go build userà la versione locale di ./lib invece di scaricare quella pubblicata. Non committare go.work (è ambiente di sviluppo).

Esercizi

Esercizio#go.m9.l4.e1
Tentativi: 0Caricamento…

Il modulo è example.com/myapp e contiene una sub-cartella utils. Importa il sub-package nel main usando il path completo.

Caricamento editor…
Mostra suggerimento

L'import path è il nome del modulo (da go.mod) + il path relativo della cartella.

Soluzione disponibile dopo 3 tentativi

Esercizio#go.m9.l4.e2
Tentativi: 0Caricamento…

Trasforma i singoli import in un import group con la sintassi import ( ... ), importando sia fmt che os.

Caricamento editor…

Soluzione disponibile dopo 3 tentativi

Quiz#go.m9.l4.e3
Pronto

Quale comando rimuove dal go.mod le dipendenze non più importate e aggiunge quelle mancanti?

Go
$ go mod ???
Opzioni di risposta