I pacchetti in Go sono il principale blocco di costruzione per organizzare il codice e gestire le aree di visibilità. Storicamente, Go ha scelto un modello semplice di importazioni e gerarchia delle cartelle per rendere la programmazione trasparente e evitare ambiguità nella risoluzione delle dipendenze, come è avvenuto in C/C++ e Java. Il problema che Go risolve è creare una struttura di progetto chiara, prevenire conflitti di nomi e garantire l'indipendenza dei moduli l'uno dall'altro.
Problema: Senza un approccio unificato all'organizzazione, è impossibile scalare l'applicazione, si verifica duplicazione, conflitti di nomi e dipendenze cicliche. È importante monitorare esplicitamente l'area di visibilità degli oggetti.
Soluzione: Ogni cartella contiene un file con un pacchetto (package somepackage), il nome della cartella e il nome del pacchetto coincidono secondo le migliori pratiche. L'importazione avviene tramite la parola chiave import, e diventano esportabili solo gli oggetti con la lettera maiuscola. La gestione delle dipendenze avviene tramite go modules (go.mod).
Esempio di struttura e importazione:
// internal/mathops/add.go package mathops func Add(a, b int) int { return a + b } // main.go package main import ( "fmt" "myservice/internal/mathops" ) func main() { fmt.Println(mathops.Add(2, 3)) }
Caratteristiche principali:
È possibile dichiarare più pacchetti diversi in una stessa cartella?
No, tutti i file in una cartella devono appartenere a un unico pacchetto.
Le funzioni diventeranno esportabili se hanno un nome con la lettera maiuscola, anche se il pacchetto è chiamato con la lettera minuscola?
Sì, l'esportazione dipende solo dalla prima lettera del nome dell'oggetto (funzione, tipo, variabile), e non dal nome del pacchetto.
È possibile importare un pacchetto con un alias diverso e questo influenzerà la visibilità delle funzioni?
Sì, è possibile. L'alias influisce solo su come si fa riferimento al pacchetto, ma non modifica l'area di visibilità:
import mymath "myservice/internal/mathops" mymath.Add(1,2)
Un sviluppatore mette tutte le funzioni in un unico file "utils.go" nel pacchetto main, senza separare la logica aziendale in pacchetti distinti.
Pro:
Contro:
Logica aziendale, utility, gestori, modelli di dati sono separati in pacchetti indipendenti: mathops, user, storage, api. Importazione rigorosamente dedicata, ogni pacchetto testato separatamente.
Pro:
Contro: