Ceci est une ancienne révision du document !
Ce tutoriel propose de créer deux modules:
Dans ce tutoriel on va :
En Go, le module est l'unité de distribution du code. Il permet de distribuer une collection de paquetages. Par exemple on peut vouloir créer un module contenant des paquetages groupant des fonctions d'analyse financière. Toutes les applications ayant besoin de faire de l'analyse financière pourront bénéficier du code. Pour plus d'informations voir la documentation officielle développement et publication des modules.
Le code en Go est regroupé en paquetages et les paquetages sont groupés et distribués dans des modules. Le module déclare les dépendances nécessaires pour l'exécution du code incluant la version de Go et l'ensemble des autres modules requis.
Lorsqu'on ajouter ou améliore les fonctionnalités d'un module, on publie une nouvelle version du module. Les développeurs qui appellent/utilisent les fonctions de votre module mettent à jour les paquetages et testent les nouvelles versions avant de passer en production.
Déclarer votre nouveau module en utilisant la commande go mod init
et en fournissant le chemin vers le module. Si vous souhaitez publier votre module se devra être un chemin depuis lequel le module sera téléchargeable par les outils Go : cela pourrait être votre dépôt de code.
# créer un repertoire pour le code mkdir greetings && cd greetings # initialise le module go mod init example.com/greetings
La commande go mod init crée le fichier go.mod qui permet le suivi des dépendances. Pour le moment le fichier ne contient que le nom du module et la version de Go supportée.
cat go.mod module example.com/greetings go 1.20
Lorsque des dépendances seront ajoutées, le fichier go.mod indiquera les versions des modules desquelles dépend votre code. Cela permet de garder la compilation reproductible et offre un contrôle direct sur les versions des modules à utiliser.
Via votre éditeur créer le fichier greetings.go avec le contenu suivant :
package greetings import "fmt" // Hello retourne un message de bienvenue à la personne désignée func Hello( name string) string { message := fmt.Sprintf("Salut, %v. Bienvenue!", name) return message }
Dans ce code on a:
La fonction Hello() prend un argument nommé de type chaîne de caractères et retourne une chaîne de caractères. En Go les fonctions commençant par une majuscule peuvent être appelées en dehors du paquetage. En Go ce comportement est désigné “export des noms”.
L'opérateur :=
est un raccourci permettant de déclarer et d'initialiser une variable en une seule ligne. Go utilise l'instruction à droite de l'opérateur pour déterminer le type de la variable.
Nous allons ici écrire le code appelant la fonction Hello() du module greetings.
Créer un répertoire hello au même niveau que greetings
cd .. mkdir hello
Après cette opération on a donc l'arborescence suivante
. ├── grettings │ ├── go.mod │ └── greetings.go └── hello
On entre dans le répertoire hello et on initialise le suivi du module :
go mod init example.com/hello
Ouvrir l'éditeur et créer le fichier hello.go avec le contenu suivant :
package main import ( "fmt" "example.com/greetings" ) func main() { msg := greetings.Hello("Yoann") fmt.Println(msg) }
Dans ce code :
On doit maintenant éditer le module “example.com/hello” pour qu'il utilise le module local “example.com/greetings”.
Dans le cas où le module est publié les outils Go peuvent le télécharger. Ici ce n'est pas le cas : il faut donc adapter le module “example.com/hello” pour qu'il puisse trouver le module “example.com/greetings” sur le système de fichier local. Depuis la ligne de commande :
go mod edit -replace example.com/greetings=../grettings
La commande spécifie que “example.com/greetings” devra être remplacé par “../grettings” lors du calcul de dépendances. Après exécution de la commande, le fichier go.mod doit contenir une directive replace :
cat go.mod module example.com/hello go 1.20 replace example.com/greetings => ../greetings
Toujours depuis la ligne de commande dans le répertoire hello, exécuter la commande go mod tidy
pour synchroniser les dépendances du module “example.com/hello”, ajoutant ce qui est requis par le code mais pas encore suivi dans le module.
go mod tidy
Après exécution de la commande le ficheir go.mod doit être de la forme :
module example.com/hello go 1.20 replace example.com/greetings => ../grettings require example.com/greetings v0.0.0-00010101000000-000000000000
La commande a bien trouvé le code dans le répertoire local ../grettings et introduit la directive require
. Cette dépendance a été créée par l'import du paquetage greetings dans hello.go
LEn complément du module on retrouve une pseudo-version générée à la place de la version semantique (semantic version number). La documentation officielle décrit en détail le versionning des modules.
go run .
Salut, Yoann. Bienvenue!
La gestion des erreurs est nécessaire à la production d' un code solide. On va maintenant aborder la génération d'une erreur depuis le module 'greetings' et sa gestion par le module appelant 'main'.
Via l'éditeur, on modifie le fichier greetings/greetings.go
comme proposé ci-dessous:
package greetings import ( "errors" "fmt" ) // Hello returns a greeting for the named person. func Hello(name string) (string, error) { // If no name was given, return an error with a message. if name == "" { return "", errors.New("empty name") } // If a name was received, return a value that embeds the name // in a greeting message. message := fmt.Sprintf("Hi, %v. Welcome!", name) return message, nil }
A propos des modifications apportées:
On peut à présent modifier le code appelant dans le fichier hello/hello.go
:
package main import ( "fmt" "log" "example.com/greetings" ) func main() { //Définition de propriétés du Logger log.Default().SetPrefix("greetings: ") //Désactive l'afficahge du timestamp, du fichier source et du numero //de ligne log.SetFlags((0)) msg, err := greetings.Hello("Yoann") //Si une erreur est retournée, elle est affichée dans la console //et le programme s'arrête if err != nil { log.Fatal(err) } //Affiche le message dans la console fmt.Println(msg) }