Maison >développement back-end >Golang >Quelle est la fonction de la commande go generate ?

Quelle est la fonction de la commande go generate ?

青灯夜游
青灯夜游original
2023-01-30 15:07:171220parcourir

La commande « go generate » est utilisée pour générer automatiquement un certain type de code avant la compilation ; elle est souvent utilisée pour générer automatiquement du code, et elle peut générer du code basé sur le code source avant que le code ne soit compilé. Lorsque la commande "go generate" est exécutée, elle analysera les fichiers de code source liés au package actuel, trouvera tous les commentaires spéciaux contenant "//go:generate", extraira et exécutera la commande suivant le commentaire spécial.

Quelle est la fonction de la commande go generate ?

L'environnement d'exploitation de ce tutoriel : système Windows 7, GO version 1.18, ordinateur Dell G3.

Le langage Go fournit une série d'outils puissants. L'utilisation flexible de ces outils peut faciliter le développement de notre projet. L'ensemble d'outils comprend les éléments suivants.

bug         start a bug report
build       compile packages and dependencies
clean       remove object files and cached files
doc         show documentation for package or symbol
env         print Go environment information
fix         update packages to use new APIs
fmt         gofmt (reformat) package sources
generate    generate Go files by processing source
get         add dependencies to current module and install them
install     compile and install packages and dependencies
list        list packages or modules
mod         module maintenance
run         compile and run Go program
test        test packages
tool        run specified go tool
version     print Go version
vet         report likely mistakes in packages

Le code source de l'outil se trouve dans $GOPATH/src/cmd/internal Cet article traite principalement de la génération de l'outil Go.

outil d'automatisation du langage Go


La commande go generate est une commande nouvellement ajoutée dans la version 1.4 du langage Go. Elle est souvent utilisée pour générer automatiquement du code. Elle peut générer du code basé sur le code source avant que le code ne soit compilé. . Lors de l'exécution de go generate, il analysera les fichiers de code source liés au package actuel, trouvera toutes les instructions de commentaire contenant "//go:generate", extraira et exécutera la commande après le commentaire, et la commande sera un programme exécutable. Le processus est similaire à l’appel et à l’exécution d’un script shell. Comment utiliser

Ce commentaire spécial doit être inclus dans le . allez au milieu du fichier de code source. Chaque fichier de code source peut contenir plusieurs commentaires spéciaux générés. go generate ne sera pas déclenché par des commandes telles que go build, go get, go test, etc., et doit être utilisé explicitement par le développeur. L'exécution de la commande est en série. Si une erreur se produit, les commandes suivantes ne seront pas exécutées.

    Les commentaires spéciaux doivent commencer par "//go:generate", sans espace après la double barre oblique.
  • La commande d'exécution doit être un programme exécutable sous le système PATH (echo $PATH).

Exemple d'utilisation

//go:generate command argument...
Exécutez la commande go generate

$ go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]
  • Implémentez la méthode String pour les constantes d'énumération
  • Après avoir lu la brève introduction ci-dessus pour générer, les lecteurs peuvent je ne ressens pas ça La puissance de l'outil, Xiaocai Knife propose un scénario d'application classique de cet outil : implémenter la méthode String pour les constantes d'énumération.
  • Un autre outil officiel, stringer, doit être mentionné ici, qui peut écrire automatiquement la méthode String() pour un ensemble de constantes entières. Étant donné que Stringer ne fait pas partie de l'ensemble d'outils de la version officielle de Go, nous devons l'installer nous-mêmes et exécuter la commande suivante.
package mainimport "fmt"//go:generate echo GoGoGo!//go:generate go run main.go//go:generate echo $GOARCH $GOOS $GOFILE $GOLINE $GOPACKAGEfunc main() {
 fmt.Println("go rum main.go!")}
  • Voici un exemple cité dans la documentation du stringer. Le code est le suivant, qui définit un ensemble de constantes entières de différents types de pilules.
  • $ go generate
    GoGoGo!go rum main.go!amd64 darwin main.go 7 main
    Pour le débogage ou d'autres raisons, nous voulons que ces constantes soient imprimées, ce qui signifie que Pill a une méthode avec une signature.

    go get golang.org/x/tools/cmd/stringer
    Pour y parvenir, c’est très simple.
    package painkillertype Pill intconst (
        Placebo Pill = iota
        Aspirin
        Ibuprofen
        Paracetamol
        Acetaminophen = Paracetamol)
    Imaginez, si nous ajoutons un lot de noms de médicaments à la liste des pilules, chaque fois que le nom du médicament est ajouté ou modifié, la fonction de signature correspondante doit également être modifiée. Cela ne serait-il pas fastidieux et susceptible d'être manqué ou erroné ? Pour le moment, nous pouvons résoudre ce problème via go generate + stringer. C'est très simple, il suffit d'ajouter une instruction de commentaire au code qui définit Pill.
    func (p Pill) String() string
    La commande ci-dessus représente l'exécution de l'outil stringer pour générer une méthode String pour le type Pill. Par défaut, elle est sortie dans le fichier pill_string.go.
    func (p Pill) String() string {
        switch p {
        case Placebo:
            return "Placebo"
        case Aspirin:
            return "Aspirin"
        case Ibuprofen:
            return "Ibuprofen"
        case Paracetamol: // == Acetaminophen
            return "Paracetamol"
        }
        return fmt.Sprintf("Pill(%d)", p)}
    De cette façon, chaque fois que nous modifions le type de pilule, tout ce que nous avons à faire est d'exécuter l'instruction suivante.

    //go:generate stringer -type=Pill
    Bien sûr, si vous trouvez cela gênant ou si vous craignez d'oublier d'exécuter l'instruction generate. Ensuite, vous pouvez écrire l'instruction go generate dans le Makefile et la placer avant la commande go build pour automatiser la génération et la compilation de code.

    Il convient de mentionner que dans les documents du code source Go, la solution go generate+stringer est largement utilisée pour implémenter la méthode String pour les constantes d'énumération. Sous le code source du Go 1.14.1 natif de Xiaocai Knife, il existe un total de 23 utilisations, comme suit.



    Résumé

    Cet article présente principalement ce qu'est la génération et ce qu'elle peut faire. Si vous souhaitez comprendre en profondeur sa logique de mise en œuvre interne, vous pouvez consulter le processus détaillé de génération de code dans Go. le code source, tel que le passage sous le package de tri genzfunc.go, implémente la génération de zfuncversion.go. Dans le trésor du code source Go, vous pouvez trouver de nombreuses logiques d'implémentation similaires, veuillez vous référer à ce qui suit.

    Ils utilisent les bibliothèques fournies par le compilateur Go, notamment go/ast pour définir des arbres de syntaxe abstraite, go/parser pour analyser les arbres de syntaxe abstraite, go/format pour analyser le formatage du code, go/token pour les balises lexicales Go, etc. . Analysez le fichier source et générez un nouveau code selon le modèle existant. Ce processus est similaire à l'utilisation de modèles pour générer des fichiers HTML dans les services Web.

    【Recommandations associées : Tutoriel vidéo Go, Enseignement de la programmation

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn