Les packages en Go sont le principal bloc de construction pour l'organisation du code et la gestion des portées. Historiquement, Go a choisi un modèle d'importation et une hiérarchie de dossiers simples pour rendre la programmation transparente et éviter les incertitudes liées à la résolution des dépendances, comme on le voit en C/C++ et Java. Le problème que Go résout est la création d'une structure de projet claire, la prévention des conflits de noms et l'indépendance des modules les uns par rapport aux autres.
Problème : Sans approche unifiée pour l'organisation, il est impossible d'évoluer l'application, ce qui entraîne des duplications, des conflits de noms, des dépendances cycliques. Il est important de surveiller explicitement la portée des objets.
Solution : Chaque répertoire contient un fichier avec le package (package somepackage), le nom du répertoire et le nom du package coïncident selon les meilleures pratiques. L'importation se fait via le mot-clé import, et seuls les objets commençant par une lettre majuscule sont exportés. La gestion des dépendances se fait via les modules Go (go.mod).
Exemple de structure et d'importation :
// 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)) }
Caractéristiques clés :
Peut-on déclarer plusieurs packages différents dans un même répertoire ?
Non, tous les fichiers dans un répertoire doivent appartenir à un seul package.
Les fonctions deviendront-elles exportées si elles ont un nom avec une majuscule, alors que le package est nommé avec une minuscule ?
Oui, l'exportation dépend uniquement de la première lettre du nom de l'objet (fonction, type, variable), et non du nom du package.
Peut-on importer un package avec un alias différent, et cela influence-t-il la portée des fonctions ?
Oui, c'est possible. L'alias n'influe que sur le nom utilisé pour accéder au package, mais ne change pas la portée :
import mymath "myservice/internal/mathops" mymath.Add(1,2)
Le développeur place toutes les fonctions dans un seul fichier "utils.go" dans le package main, sans distinguer la logique métier en packages séparés.
Avantages :
Inconvénients :
La logique métier, les utilitaires, les gestionnaires, les modèles de données sont extraits dans des packages indépendants : mathops, user, storage, api. L'importation se fait strictement par destination, chaque package est testé séparément.
Avantages :
Inconvénients :