00
:
00
:
00
:
00
•Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Pacchetti in Go

In Go, i pacchetti (packages) sono il meccanismo fondamentale per organizzare e riutilizzare il codice. Ogni file Go appartiene a un pacchetto, e ogni programma Go e composto da uno o piu pacchetti.

Cos’e un Pacchetto

Un pacchetto e una collezione di file Go nella stessa directory che condividono la stessa dichiarazione package. I pacchetti permettono di:

  • Organizzare il codice in unita logiche
  • Controllare la visibilita dei nomi (esportazione)
  • Riutilizzare il codice tra progetti diversi

Dichiarazione del Pacchetto

Ogni file Go inizia con una dichiarazione di pacchetto:

package main // pacchetto eseguibile

// oppure

package matematica // pacchetto libreria

Il pacchetto main e speciale: indica un programma eseguibile e deve contenere una funzione main().

Nomi Esportati vs Non Esportati

In Go, la visibilita e determinata dalla lettera iniziale del nome:

  • Maiuscola = esportato (visibile dall’esterno del pacchetto)
  • Minuscola = non esportato (privato al pacchetto)
package utente

// Esportato: accessibile da altri pacchetti
type Profilo struct {
    Nome  string // esportato
    Email string // esportato
    eta   int    // non esportato
}

// Esportato
func NuovoProfilo(nome, email string, eta int) *Profilo {
    return &Profilo{Nome: nome, Email: email, eta: eta}
}

// Non esportato: accessibile solo all'interno del pacchetto 'utente'
func validaEmail(email string) bool {
    return len(email) > 0
}

Da un altro pacchetto:

package main

import "mioprogetto/utente"

func main() {
    p := utente.NuovoProfilo("Marco", "marco@email.it", 30)
    fmt.Println(p.Nome)  // OK: Nome e esportato
    // fmt.Println(p.eta) // ERRORE: eta non e esportato
    // utente.validaEmail("test") // ERRORE: validaEmail non e esportato
}

Importare Pacchetti

I pacchetti si importano con la parola chiave import:

// Importazione singola
import "fmt"

// Importazione multipla (forma raggruppata)
import (
    "fmt"
    "math"
    "strings"

    "mioprogetto/utente" // pacchetto locale
)

Alias per i Pacchetti

E possibile assegnare un alias a un pacchetto importato:

import (
    f "fmt"                    // alias 'f' per fmt
    str "strings"              // alias 'str' per strings
    _ "database/sql/driver"    // import per effetti collaterali (init)
    . "math"                   // import diretto (sconsigliato)
)

func main() {
    f.Println("Ciao") // usa l'alias
    str.ToUpper("go") // usa l'alias
}

L’underscore _ importa il pacchetto solo per eseguire la sua funzione init(), senza usarne i nomi.

Inizializzazione del Pacchetto

Variabili a Livello di Pacchetto

Le variabili a livello di pacchetto vengono inizializzate prima della funzione main():

package config

var (
    NomeApp    = "MiaApp"
    Versione   = "1.0.0"
    MaxUtenti  = 100
)

La Funzione init()

Ogni file Go puo contenere una o piu funzioni init() che vengono eseguite automaticamente all’inizializzazione del pacchetto:

package database

import (
    "fmt"
    "os"
)

var connessione string

func init() {
    connessione = os.Getenv("DATABASE_URL")
    if connessione == "" {
        connessione = "localhost:5432"
    }
    fmt.Println("Database configurato:", connessione)
}

L’ordine di inizializzazione e:

  1. Variabili a livello di pacchetto
  2. Funzioni init() nell’ordine in cui appaiono nel file
  3. Se ci sono piu file, in ordine alfabetico dei nomi dei file

Nota: non e possibile chiamare init() esplicitamente. Viene invocata automaticamente dal runtime.

Panoramica della Libreria Standard

Go ha una libreria standard ricca e ben progettata. Ecco i pacchetti piu importanti:

import (
    "fmt"       // formattazione e stampa
    "os"        // interfaccia con il sistema operativo
    "io"        // interfacce per I/O
    "strings"   // manipolazione stringhe
    "strconv"   // conversioni stringa <-> numeri
    "math"      // funzioni matematiche
    "sort"      // algoritmi di ordinamento
    "net/http"  // client e server HTTP
    "encoding/json" // codifica/decodifica JSON
    "time"      // gestione del tempo
    "context"   // contesto per cancellazione e timeout
    "sync"      // primitive di sincronizzazione
    "errors"    // gestione errori
    "log"       // logging
    "testing"   // framework di test
)

Creare i Propri Pacchetti

Ecco come organizzare un progetto con pacchetti personalizzati:

Struttura del progetto:

mioprogetto/
    go.mod
    main.go
    matematica/
        operazioni.go
        costanti.go
    utilita/
        stringhe.go

File matematica/operazioni.go:

package matematica

// Somma restituisce la somma di due interi
func Somma(a, b int) int {
    return a + b
}

// Media calcola la media di uno slice di float64
func Media(numeri []float64) float64 {
    if len(numeri) == 0 {
        return 0
    }
    somma := 0.0
    for _, n := range numeri {
        somma += n
    }
    return somma / float64(len(numeri))
}

File matematica/costanti.go:

package matematica

const (
    Pi     = 3.14159265358979
    E      = 2.71828182845904
)

File main.go:

package main

import (
    "fmt"
    "mioprogetto/matematica"
)

func main() {
    risultato := matematica.Somma(3, 7)
    fmt.Println("Somma:", risultato)

    media := matematica.Media([]float64{10, 20, 30})
    fmt.Println("Media:", media)

    fmt.Println("Pi greco:", matematica.Pi)
}

Convenzioni sui Nomi dei Pacchetti

Go ha convenzioni chiare per i nomi dei pacchetti:

  1. Minuscolo: i nomi dei pacchetti sono sempre in minuscolo (strings, non Strings)
  2. Parola singola: preferire nomi brevi e descrittivi (http, json, time)
  3. No underscore o camelCase: usare httputil, non http_util o httpUtil
  4. Non ripetere il nome del pacchetto nei nomi esportati: http.Server, non http.HTTPServer

Conclusione

I pacchetti sono il fondamento dell’organizzazione del codice in Go. Comprendere come creare pacchetti, controllare la visibilita con le lettere maiuscole e minuscole, e sfruttare la funzione init() e la libreria standard e essenziale per scrivere codice Go ben strutturato e manutenibile. La semplicita del sistema di pacchetti di Go e uno dei suoi punti di forza principali.