Informazioni sui pacchetti

Completato

I pacchetti in Go sono simili alle librerie o ai moduli in altri linguaggi di programmazione. È possibile creare un pacchetto del codice e riutilizzarlo altrove. Il codice sorgente di un pacchetto può essere distribuito in più di un file .go. Finora è stato scritto il pacchetto main e sono stati usati alcuni riferimenti ad altri pacchetti nativi.

In questa sezione verranno descritte le caratteristiche di un pacchetto. Si apprenderà anche come crearne uno e come utilizzare i pacchetti esterni.

Pacchetto main

Come probabilmente si è notato, anche il programma più semplice in Go deve fare parte di un pacchetto. In genere, il pacchetto predefinito è il pacchetto main, quello usato finora. Se un programma fa parte del pacchetto main, Go genera un file binario. Quando il file viene eseguito, chiama la funzione main().

In altre parole, quando si usa il pacchetto main, il programma produrrà un eseguibile autonomo. Tuttavia, quando un programma fa parte di un pacchetto diverso da main, Go non genera un file binario. Genera un file di archivio del pacchetto (un file con estensione .a).

In Go i nomi dei pacchetti seguono una convenzione. Il nome di un pacchetto corrisponde all'ultima parte del percorso di importazione. Ad esempio, la libreria standard Go contiene un pacchetto denominato math/cmplx, che fornisce codice utile per l'uso di numeri complessi. Il percorso di importazione di questo pacchetto è math/cmplx e viene importato nel modo seguente:

import "math/cmplx"

Per fare riferimento a oggetti presenti nel pacchetto, usare il nome del pacchetto, cmplx, come nell'esempio seguente:

cmplx.Inf()

Si vedrà ora come creare un pacchetto.

Creare un pacchetto

Creare una nuova directory nella directory $GOPATH/src denominata calculator. Creare un file denominato sum.go. L'albero di directory dovrebbe essere simile al seguente:

src/
  calculator/
    sum.go

Inizializzare il file sum.go con il nome del pacchetto:

package calculator

È ora possibile iniziare a scrivere le funzioni e le variabili per il pacchetto. Diversamente da altri linguaggi di programmazione, Go non offre le parole chiave public o private per indicare se una variabile o una funzione può essere chiamata dall'esterno o all'interno del pacchetto. Tuttavia, Go segue due semplici regole:

  • Se si vuole che un elemento sia privato, iniziarne il nome con una lettera minuscola.
  • Se si vuole che un elemento sia pubblico, iniziarne il nome con una lettera maiuscola.

Aggiungere quindi il codice seguente al pacchetto della calcolatrice da creare:

package calculator

var logMessage = "[LOG]"

// Version of the calculator
var Version = "1.0"

func internalSum(number int) int {
    return number - 1
}

// Sum two integer numbers
func Sum(number1, number2 int) int {
    return number1 + number2
}

È opportuno evidenziare alcuni aspetti in questo codice:

  • La variabile logMessage può essere chiamata solo dall'interno del pacchetto.
  • La variabile Version può essere raggiunta da qualsiasi posizione. È consigliabile includere un commento per descrivere lo scopo di questa variabile. Questa descrizione è utile per chiunque usi il pacchetto.
  • La funzione internalSum può essere chiamata solo dall'interno del pacchetto.
  • La funzione Sum può essere raggiunta da qualsiasi posizione. È consigliabile includere un commento per descrivere lo scopo della funzione.

Per verificare che tutto funzioni, è possibile eseguire il comando go build nella directory calculator. Si noterà che non viene generato alcun file binario eseguibile.

Creare un modulo

Le funzionalità della calcolatrice sono state inserite in un pacchetto. È ora necessario inserire tale pacchetto in un modulo. I moduli Go contengono in genere pacchetti che offrono funzionalità correlate. Un modulo del pacchetto specifica anche il contesto necessario per consentire a Go di eseguire il codice raggruppato. Queste informazioni contestuali includono la versione di Go per cui è stato scritto il codice.

Inoltre, i moduli consentono ad altri sviluppatori di fare riferimento a versioni specifiche del codice e di semplificare l'uso delle dipendenze. Un altro vantaggio è che il codice sorgente del programma non deve necessariamente esistere nella directory $GOPATH/src. Senza questa restrizione è più semplice usare diverse versioni del pacchetto in altri progetti allo stesso tempo.

Per creare un modulo per il pacchetto calculator, eseguire quindi questo comando nella directory radice ($GOPATH/src/calculator):

go mod init github.com/myuser/calculator

Dopo aver eseguito questo comando, github.com/myuser/calculator diventa il nome del modulo. Questo nome verrà usato per farvi riferimento in altri programmi. Il comando crea anche un nuovo file denominato go.mod. Infine, l'albero di directory è ora come segue:

src/
  calculator/
    go.mod
    sum.go

Il contenuto del file go.mod dovrebbe risultare simile al seguente. (La versione di Go potrebbe essere diversa.)

module github.com/myuser/calculator

go 1.14

Per fare riferimento al pacchetto calculator in altri programmi, è necessario importarlo usando il nome del modulo. In questo caso il nome è github.com/myuser/calculator. Verrà ora esaminato un esempio di come usare questo pacchetto.

Nota

La gestione delle dipendenze in Go non è stata facile storicamente. Il sistema di gestione delle dipendenze è ancora in corso di miglioramento. Per altre informazioni sui moduli, vedere questa serie di post pubblicati nel blog di Go.

Fare riferimento a un pacchetto locale (modulo)

A questo punto si vedrà come è possibile usare il pacchetto, continuando con l'applicazione di esempio usata finora. Questa volta, invece di usare la funzione sum nel pacchetto main, si userà quella creato in precedenza nel pacchetto calculator.

La struttura di directory e file è ora come segue:

src/
  calculator/
    go.mod
    sum.go
  helloworld/
    main.go

Si userà questo codice per il file $GOPATH/src/helloworld/main.go:

package main

import (
  "fmt"
  "github.com/myuser/calculator"
)

func main() {
    total := calculator.Sum(3, 5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.Version)
}

Si noti che l'istruzione Import usa il nome del pacchetto creato: calculator. Per chiamare la funzione Sum da tale pacchetto, è necessario includere il nome del pacchetto come in calculator.Sum. Infine, è ora possibile accedere alla variabile Version. Viene chiamata in questo modo: calculator.Version.

Se si prova a eseguire il programma ora, non funzionerà. È necessario comunicare a Go che si stanno usando moduli per fare riferimento ad altri pacchetti. A tale scopo, eseguire questo comando nella directory $GOPATH/src/helloworld:

go mod init helloworld

Nel comando precedente helloworld è il nome del progetto. Questo comando crea un nuovo file go.mod, quindi l'albero di directory è ora simile al seguente:

src/
  calculator/
    go.mod
    sum.go
  helloworld/
    go.mod
    main.go

Se si apre il file go.mod si vedrà codice simile al seguente. (La versione di Go potrebbe essere diversa.)

module helloworld

go 1.14

Poiché si fa riferimento a una copia locale del modulo, è necessario comunicare a Go che non si vuole usare una posizione remota. Occorre quindi modificare manualmente il file go.mod in modo da includere il riferimento, come indicato di seguito:

module helloworld

go 1.14

require github.com/myuser/calculator v0.0.0

replace github.com/myuser/calculator => ../calculator

La parola chiave replace specifica di usare una directory locale anziché una posizione remota per il modulo. In questo caso, poiché i programmi helloworld e calculator si trovano in $GOPATH/src, il percorso è semplicemente ../calculator. Se l'origine del modulo si trova in un percorso diverso, è necessario definire il percorso locale.

Eseguire il programma usando questo comando:

go run main.go

L'output deve essere il seguente:

8
Version:  1.0

Sfida 1

Cosa accade se si tenta di chiamare la variabile logMessage o la funzione internalSum dal pacchetto calculator nell'applicazione principale? Funziona? Basta provare.

Soluzione della sfida:

package main

import (
 "fmt"
 "github.com/myuser/calculator"
)

func main() {
    total := calculator.internalSum(5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.logMessage)
}

Pubblicare un pacchetto

La pubblicazione di un pacchetto Go è piuttosto semplice. È sufficiente rendere disponibile pubblicamente il codice sorgente del pacchetto. La maggior parte degli sviluppatori usa GitHub per rendere disponibili i pacchetti al pubblico; per questo motivo a volte si troveranno troverai riferimenti a github.com nelle istruzioni di importazione.

Ad esempio, se si vuole pubblicare il pacchetto calculator nel proprio account GitHub, è necessario creare un repository denominato calculator. L'URL dovrebbe essere simile al seguente:

https://github.com/myuser/calculator

Si assegnerà una versione ai pacchetti contrassegnando il repository in questo modo:

git tag v0.1.0
git push origin v0.1.0

Gli sviluppatori che vogliono usare il pacchetto (incluso l'autore) faranno riferimento al pacchetto in questo modo:

import "github.com/myuser/calculator"

Si vedrà ora in maggiore dettaglio come fare riferimento a pacchetti di terze parti.

Fare riferimento a pacchetti esterni (di terze parti)

In alcuni casi è necessario che i programmi facciano riferimento a pacchetti scritti da altri sviluppatori. In genere, questi pacchetti sono disponibili in GitHub. Le istruzioni seguenti per fare riferimento a pacchetti di terze parti funzionano sia se si sta sviluppando un pacchetto (un pacchetto diverso da main) che un programma autonomo (il pacchetto main).

Il codice seguente consente di aggiungere un riferimento al pacchetto rsc.io/quote:

package main

import (
    "fmt"
    "github.com/myuser/calculator"
    "rsc.io/quote"
)

func main() {
    total := calculator.Sum(3, 5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.Version)
    fmt.Println(quote.Hello())
}

Se si usa Visual Studio Code, il file go.mod viene aggiornato quando si salva il file. Ora ha questo aspetto:

module helloworld

go 1.14

require (
    github.com/myuser/calculator v0.0.0
    rsc.io/quote v1.5.2
)

replace github.com/myuser/calculator => ../calculator

Si noti come rsc.io/quote fa riferimento a una versione specifica del pacchetto. Quando occorre aggiornare le dipendenze del programma, sarà necessario modificare la versione qui.

Eseguire di nuovo il programma usando questo comando:

go run main.go

L'output dovrebbe essere simile al seguente:

8
Version:  1.0
Hello, world.

Tutti i riferimenti futuri ai pacchetti di terze parti dovranno essere inclusi nel file go.mod. Quando si esegue o si compila l'applicazione, Go scaricherà tutte le relative dipendenze.