Ligne de commande

Les commandes dans Go comprennent toute une chaîne d'outils, ces commandes couvrent la documentation, le formatage, l'inspection du code, la compilation, les tests, la gestion des dépendances et bien d'autres aspects, on peut dire qu'elles couvrent tous les aspects du développement Go.
bug Signaler un bug
build Compiler les packages et les dépendances
clean Nettoyer les fichiers objets
doc Afficher la documentation dans le code source
env Afficher les informations sur les variables d'environnement Go
fix Résoudre les problèmes de compatibilité API dus aux changements de version de go
fmt Formater le code source
generate Génération de code
get Ajouter des dépendances
install Installer et compiler les packages
list Commande de liste de packages/modules
mod Commande de maintenance des modules
work Commande de maintenance des espaces de travail
run Compiler et exécuter
test Tester
tool Exécuter l'outil go spécifié
version Afficher les informations de version de go
vet Analyser et signaler les problèmes potentiels dans le code sourceCet article décrit et présente simplement leur utilisation, tout le contenu est référencé depuis la documentation officielle, pour en savoir plus sur les détails, rendez-vous sur cmd/go.
help
La première commande à connaître est la commande help, qui permet de lire l'utilisation des commandes. Il y a deux façons de l'utiliser, si vous souhaitez obtenir des informations d'utilisation brèves, vous pouvez ajouter le drapeau -h après la commande spécifiée, par exemple
$ go env -h
usage: go env [-json] [-u] [-w] [var ...]
Run 'go help env' for details.Go affichera brièvement l'utilisation de la commande, et il indique également que pour obtenir des informations plus détaillées, vous devez utiliser la commande help
$ go help env
usage: go env [-json] [-u] [-w] [var ...]
Env prints Go environment information.
By default env prints information as a shell script
(on Windows, a batch file). If one or more variable
names is given as arguments, env prints the value of
each named variable on its own line.
The -json flag prints the environment in JSON format
instead of as a shell script.
The -u flag requires one or more arguments and unsets
the default setting for the named environment variables,
if one has been set with 'go env -w'.
The -w flag requires one or more arguments of the
form NAME=VALUE and changes the default settings
of the named environment variables to the given values.
For more about environment variables, see 'go help environment'.Utilisez habilement la commande help, grâce à elle vous pouvez obtenir beaucoup d'informations sur les commandes.
doc
$ go doc -h
Usage of [go] doc:
go doc
go doc <pkg>
go doc <sym>[.<methodOrField>]
go doc [<pkg>.]<sym>[.<methodOrField>]
go doc [<pkg>.][<sym>.]<methodOrField>
go doc <pkg> <sym>[.<methodOrField>]
For more information run
go help doc
Flags:
-C dir
change to dir before running command
-all
show all documentation for package
-c symbol matching honors case (paths not affected)
-cmd
show symbols with package docs even if package is a command
-short
one-line representation for each symbol
-src
show source code for symbol
-u show unexported symbols as well as exportedLa commande doc affiche les commentaires de documentation pour les packages, constantes, fonctions, types, variables, méthodes et même les champs de structure spécifiés. Sans aucun paramètre, elle affiche les commentaires du package actuel
$ go docVous pouvez également spécifier un package à consulter, par exemple pour afficher la documentation du package runtime
$ go doc runtime
package runtime // import "runtime"
Package runtime contains operations that interact with Go's runtime system,
such as functions to control goroutines. It also includes the low-level type
information used by the reflect package; see reflect's documentation for the
programmable interface to the run-time type system.
......Ou un certain type
$ go doc unsafe.Pointer
package unsafe // import "unsafe"
type Pointer *ArbitraryType
Pointer represents a pointer to an arbitrary type. There are four special
operations available for type Pointer that are not available for other
types:
- A pointer value of any type can be converted to a Pointer.
- A Pointer can be converted to a pointer value of any type.
- A uintptr can be converted to a Pointer.
- A Pointer can be converted to a uintptr.
...Ou une certaine fonction
$ go doc runtime.GC
package runtime // import "runtime"
func GC()
GC runs a garbage collection and blocks the caller until the garbage
collection is complete. It may also block the entire program.Elle dispose des drapeaux courants suivants
-u: Afficher les types privés-all: Afficher toute la documentation d'un package spécifié-short: Affiche uniquement une brève description en une ligne-src: Affiche le code source-cmd: Affiche également la documentation du code pour les packages qui appartiennent aux commandes go.
Par exemple, pour afficher la variable runtime.inf, qui est une variable non exposée
$ go doc -u runtime.inf
package runtime // import "runtime"
var inf = float64frombits(0x7FF0000000000000)Bien utiliser la commande doc peut vous aider à lire la documentation plus facilement.
Une autre façon de lire la documentation des commandes est de lire le code source, car la documentation de certaines commandes n'est pas écrite de manière très détaillée, alors que le code source contient des explications plus détaillées. Comme ces commandes sont toutes écrites en go, la lecture est très pratique. Ces commandes sont situées dans le package src/cmd, chaque sous-package est une commande séparée, le point d'entrée se trouve dans le fichier cmd/go/main.go
func init() {
base.Go.Commands = []*base.Command{
bug.CmdBug,
work.CmdBuild,
clean.CmdClean,
doc.CmdDoc,
envcmd.CmdEnv,
fix.CmdFix,
fmtcmd.CmdFmt,
generate.CmdGenerate,
modget.CmdGet,
work.CmdInstall,
list.CmdList,
modcmd.CmdMod,
workcmd.CmdWork,
run.CmdRun,
test.CmdTest,
tool.CmdTool,
version.CmdVersion,
vet.CmdVet,
help.HelpBuildConstraint,
help.HelpBuildmode,
help.HelpC,
help.HelpCache,
help.HelpEnvironment,
help.HelpFileType,
modload.HelpGoMod,
help.HelpGopath,
get.HelpGopathGet,
modfetch.HelpGoproxy,
help.HelpImportPath,
modload.HelpModules,
modget.HelpModuleGet,
modfetch.HelpModuleAuth,
help.HelpPackages,
modfetch.HelpPrivate,
test.HelpTestflag,
test.HelpTestfunc,
modget.HelpVCS,
}
}Ici, vous trouverez toutes les sous-commandes de go, ainsi que leurs informations de documentation d'aide.
bug
$ go help bug
usage: go bug
Bug opens the default browser and starts a new bug report.
The report includes useful system information.Cette commande n'a aucun paramètre ni drapeau, elle utilise votre navigateur par défaut pour accéder à la page des issues du dépôt github.com/golang/go, ce qui vous permet de signaler des bugs, et n'a aucune autre fonction.
version
La commande version permet d'afficher les informations de version de go.
$ go version -h
usage: go version [-m] [-v] [file ...]Sans aucun paramètre, elle affiche la version actuelle du langage go
$ go version
go version go1.21.0 windows/amd64Elle accepte également les chemins de fichiers comme paramètres, et affiche la version de go utilisée pour compiler tous les fichiers binaires identifiables dans ce chemin.
$ go version -v ./
buf.exe: go1.20.2
cobra-cli.exe: go1.21.0
dlv.exe: go1.20.2
goctl.exe: go1.20.2
goimports.exe: go1.20.2
golangci-lint.exe: go1.20.2
gopls.exe: go1.19.3
kratos.exe: go1.20.2
main.exe: go1.19.1
protoc-gen-go-grpc.exe: go1.20.2
protoc-gen-go-http.exe: go1.20.2
protoc-gen-go.exe: go1.20.2
protoc-gen-openapi.exe: go1.20.2
swag.exe: go1.21.0
wire.exe: go1.21.0Le paramètre -v indique à la commande version d'essayer d'afficher la version go des fichiers non identifiables, le paramètre -m affiche les informations de module des fichiers binaires, ainsi que certains paramètres de compilation, voici un exemple simple.
$ go version -v -m wire.exe
wire.exe: go1.21.0
path github.com/google/wire/cmd/wire
mod github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
dep github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k=
dep github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
dep golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b h1:NVD8gBK33xpdqCaZVVtd6OFJp+3dxkXuz7+U7KaVN6s=
build -buildmode=exe
build -compiler=gc
build DefaultGODEBUG=panicnil=1
build CGO_ENABLED=1
build CGO_CFLAGS=
build CGO_CPPFLAGS=
build CGO_CXXFLAGS=
build CGO_LDFLAGS=
build GOARCH=amd64
build GOOS=windows
build GOAMD64=v1go est lui-même un fichier binaire, en fait, sans aucun paramètre, go version affiche la version du langage go de son propre fichier binaire, car toute la chaîne d'outils de cmd/go est implémentée par le langage go lui-même.
env
La commande env permet d'afficher toutes les variables d'environnement go, la modification de ces variables d'environnement affectera le comportement de la chaîne d'outils go.
$ go env -h
usage: go env [-json] [-u] [-w] [var ...]
Run 'go help env' for details.Exécuter cette commande sans aucun paramètre affiche les valeurs de toutes les variables d'environnement go
$ go env
set GO111MODULE=on
set GOARCH=amd64
...Utiliser le nom d'une variable d'environnement comme paramètre permet d'afficher uniquement la valeur de cette variable
$ go env GO111MODULE
onAjouter -json permet d'afficher sa forme json
$ go env -json
{
"AR": "ar",
"CC": "gcc",
......
}Utiliser le drapeau -w, et avec un paramètre sous la forme var=value, modifie définitivement la valeur d'une variable
$ go env -w GO111MODULE=onUtiliser le drapeau -u permet de rétablir une variable à sa valeur par défaut
$ go env -u GO111MODULEExécuter go help environment permet d'afficher la description de chaque variable d'environnement
$ go help environment
The go command and the tools it invokes consult environment variables
for configuration. If an environment variable is unset or empty, the go
command uses a sensible default setting. To see the effective setting of
the variable <NAME>, run 'go env <NAME>'. To change the default setting,
run 'go env -w <NAME>=<VALUE>'. Defaults changed using 'go env -w'
are recorded in a Go environment configuration file stored in the
per-user configuration directory, as reported by os.UserConfigDir.
The location of the configuration file can be changed by setting
the environment variable GOENV, and 'go env GOENV' prints the
effective location, but 'go env -w' cannot change the default location.
See 'go help env' for details.
General-purpose environment variables:
GO111MODULE
Controls whether the go command runs in module-aware mode or GOPATH mode.
May be "off", "on", or "auto".
See https://golang.org/ref/mod#mod-commands.
GCCGO
The gccgo command to run for 'go build -compiler=gccgo'.
GOARCH
The architecture, or processor, for which to compile code.
Examples are amd64, 386, arm, ppc64.
GOBIN
The directory where 'go install' will install a command.
GOCACHE
The directory where the go command will store cached
information for reuse in future builds.
......Voici quelques variables d'environnement couramment utilisées
GOVERSION
La valeur de cette variable d'environnement dépend de la version du langage go, et le numéro de version provient du fichier $GOROOT/VERSION, qui enregistre la version actuelle de go et l'heure de construction.
$ cat $GOROOT/VERSION
go1.21.3
time 2023-10-09T17:04:35ZLa valeur de la variable runtime.Version est la même que celle de GOVERSION, et cette variable d'environnement ne peut pas être modifiée.
GOENV
Il y a un fichier de configuration par défaut nommé go.env dans le répertoire $GOROOT
$ cat $GOROOT/go.env
# This file contains the initial defaults for go command configuration.
# Values set by 'go env -w' and written to the user's go/env file override these.
# The environment overrides everything else.
# Use the Go module mirror and checksum database by default.
# See https://proxy.golang.org for details.
GOPROXY=https://proxy.golang.org,direct
GOSUMDB=sum.golang.org
# Automatically download newer toolchains as directed by go.mod files.
# See https://go.dev/doc/toolchain for details.
GOTOOLCHAIN=autoSon format est simplement key=value, les valeurs des variables d'environnement modifiées via la commande go env -w key=value seront écrites dans le fichier de configuration. Cependant, il est également possible de ne pas utiliser le fichier de configuration par défaut, la variable d'environnement GOENV peut spécifier manuellement l'adresse du fichier de configuration env, et la valeur de la variable d'environnement GOENV ne peut être remplacée que par les variables d'environnement du système d'exploitation, et ne peut pas être modifiée par la commande go env -w.
GOHOSTARCH
Représente l'architecture CPU de la machine locale, utilisée uniquement pour l'affichage, la valeur de cette variable d'environnement n'est pas lue depuis le fichier de configuration et ne peut pas être modifiée.
GOHOSTOS
Représente le système d'exploitation de la machine locale, utilisée uniquement pour l'affichage, la valeur de cette variable d'environnement n'est pas lue depuis le fichier de configuration et ne peut pas être modifiée.
GOOS
Lors de la compilation, la valeur de GOOS détermine le système cible pour lequel le code source sera compilé en fichier binaire, la valeur par défaut est GOHOSTOS, c'est-à-dire le système d'exploitation de la machine locale, il y a les options suivantes
linuxdarwinwindowsnetbsdaixandroid
Les systèmes d'exploitation réellement pris en charge ne se limitent pas à ceux-ci, utilisez la commande go tool dist list pour afficher toutes les valeurs prises en charge
$ go tool dist list | awk -F '/' '{print $1}' | awk '!seen[$0]++'
aix
android
darwin
dragonfly
freebsd
illumos
ios
js
linux
netbsd
openbsd
plan9
solaris
wasip1
windowsGOARCH
Lors de la compilation, la valeur de GOARCH détermine l'architecture CPU utilisée lors de la compilation, la valeur par défaut est GOHOSTARCH, c'est-à-dire l'architecture CPU de la machine locale, il y a les options suivantes
amd64386armppc64
Les architectures réellement prises en charge ne se limitent pas à celles-ci, utilisez la commande go tool dist list pour afficher toutes les valeurs prises en charge
$ go tool dist list | awk -F '/' '{print $2}' | awk '!seen[$0]++'
ppc64
386
amd64
arm
arm64
riscv64
wasm
loong64
mips
mips64
mips64le
mipsle
ppc64le
s390xIl est à noter que GOOS et GOARCH ne peuvent pas être combinés arbitrairement, certains systèmes d'exploitation ne prennent en charge que des architectures CPU spécifiques.
GOROOT
GOROOT représente le répertoire racine de l'installation du langage go, la valeur de GOROOT ne peut pas être modifiée directement, et ne peut être remplacée que par les variables d'environnement du système d'exploitation.
$ ls $GOROOT -1
api
bin
codereview.cfg
CONTRIBUTING.md
doc
go.env
lib
LICENSE
misc
PATENTS
pkg
README.md
SECURITY.md
src
test
VERSIONIl y a plusieurs répertoires ou fichiers importants dans le répertoire racine
lib, stocke certaines dépendances, pour l'instant il n'y a qu'une bibliothèque contenant des informations de fuseau horaire de divers pays du monde, située dans$GOROOT/lib/time, les fichiers binaires compilés ne contiendront pas ces informations de fuseau horaire.pkg, stocke certaines bibliothèques d'outils et fichiers d'en-tête, par exemple la commandego toolrecherchera les fichiers binaires de la chaîne d'outils go dans le répertoire$GOROOT/pkg/toolbin, stocke les fichiers binaires, par défaut il n'y a que les fichiers exécutablesgoetgofmt,$GOROOT/bindoit être ajouté aux variables système, sinon les commandes go ne peuvent pas être utilisées.src, stocke le code source goVERSION, ce fichier stocke les informations de version du langage gogo.env, ce fichier est le fichier de configurationenvpar défaut
GOPATH
La valeur par défaut de GOPATH est $HOME/go, la valeur de cette variable d'environnement spécifie où rechercher les fichiers importés lors de l'analyse des instructions import. Au début, avant gomod, GOPATH était spécialement utilisé pour stocker diverses bibliothèques tierces, sa structure est la suivante
GOPATH=/home/user/go
/home/user/go/
src/
foo/
bar/ (go code in package bar)
x.go
quux/ (go code in package main)
y.go
bin/
quux (installed command)
pkg/
linux_amd64/
foo/
bar.a (installed package object)Après la naissance de gomod, GOPATH est simplement devenu un endroit pour stocker les dépendances téléchargées avec go get, ainsi que pour stocker les fichiers binaires téléchargés et compilés avec go install. Il est à noter que l'emplacement de GOPATH ne peut pas être le même que GOROOT, sinon cela n'aura aucun effet.
$ go env GOBIN
warning: GOPATH set to GOROOT (/home/user/go) has no effectJusqu'à présent, au moment où j'écris cet article, la version du langage go est déjà arrivée à go1.21.3, à l'exception des projets très anciens, presque personne n'utilise plus gopath pour gérer les dépendances.
GOBIN
GOBIN est utilisé pour stocker les fichiers binaires exécutables tiers téléchargés et compilés avec go install, sa valeur par défaut est $GOPATH/bin. Comme $GOROOT/bin, ce répertoire doit être ajouté aux variables d'environnement du système d'exploitation, sinon les fichiers binaires du répertoire GOBIN ne peuvent pas être utilisés.
GOMODCACHE
GOMODCACHE représente l'emplacement de stockage des dépendances téléchargées avec go get, la valeur par défaut est $GOPATH/pkg/mod. Son format de stockage est le suivant
$GOMODCACHE/domain/username/project@versionIl y aura également un répertoire nommé sumdb au même niveau, utilisé pour stocker les informations relatives à la base de données de somme de contrôle des dépendances.
GOCACHE
Stocke les informations de cache utilisées pour la compilation, sa valeur par défaut est $HOME/.cache/go-build, un fichier README sera généré dans ce répertoire.
$ cat $(go env GOCACHE)/README
This directory holds cached build artifacts from the Go build system.
Run "go clean -cache" if the directory is getting too large.
Run "go clean -fuzzcache" to delete the fuzz cache.
See golang.org to learn more about Go.Chaque build génère de nombreux fichiers, go met en cache ces fichiers pour les réutiliser lors de la prochaine compilation.
GOTEMPDIR
Utilisé pour les fichiers temporaires générés lors de la compilation, tels que les fichiers binaires temporaires à exécuter avec go run. Sa valeur par défaut est le répertoire temporaire spécifié par le système d'exploitation, /tmp sur mac ou linux, %TEMP% sur windows, et peut également être modifié pour un emplacement spécifié par l'utilisateur.
GO111MODULE
Cette variable d'environnement indique quelle méthode utiliser pour gérer les dépendances des projets go, il y a trois valeurs disponibles
off, désactive gomod, utilise gopath, et ignore tous les fichiersgo.modon, utilise gomod, n'utilise pas gopath (par défaut).auto, détection automatique, si le fichier du projet contientgo.mod, utilise gomod pour la gestion
TIP
Pourquoi s'appelle-t-il GO111MODULE, et pas simplement GOMODULE, parce que gomod a été introduit pour la première fois dans la version go1.11.
GOPROXY
Le proxy de module go, la valeur par défaut est https://proxy.golang.org,direct, les url sont séparées par des virgules, direct signifie utiliser directement VCS pour sauter le proxy de module, ce dernier n'est exécuté que si le premier n'est pas accessible, il y a aussi une option disponible off, qui signifie interdire le téléchargement de tout module. En outre, GOPROXY peut également être une adresse de fichier, par exemple
GOPROXY=file://$(go env GOMODCACHE)/cache/downloadUtiliser go get -x permet de voir les commandes exécutées lors du processus de téléchargement des dépendances, et donc de savoir si le proxy est utilisé.
$ go get -x github.com/spf13/cast
# get https://goproxy.cn/github.com/@v/list
# get https://goproxy.cn/github.com/spf13/cast/@v/list
# get https://goproxy.cn/github.com/spf13/@v/list
# get https://goproxy.cn/github.com/spf13/@v/list: 404 Not Found (0.118s)
# get https://goproxy.cn/github.com/@v/list: 404 Not Found (0.197s)
# get https://goproxy.cn/github.com/spf13/cast/@v/list: 200 OK (0.257s)
# get https://goproxy.cn/github.com/spf13/cast/@v/v1.5.1.info
# get https://goproxy.cn/github.com/spf13/cast/@v/v1.5.1.info: 200 OK (0.013s)
# get https://goproxy.cn/github.com/spf13/cast/@v/v1.5.1.mod
# get https://goproxy.cn/github.com/spf13/cast/@v/v1.5.1.mod: 200 OK (0.015s)
# get https://goproxy.cn/sumdb/sum.golang.org/supported
# get https://goproxy.cn/sumdb/sum.golang.org/supported: 200 OK (0.064s)
# get https://goproxy.cn/sumdb/sum.golang.org/lookup/github.com/spf13/cast@v1.5.1
# get https://goproxy.cn/sumdb/sum.golang.org/lookup/github.com/spf13/cast@v1.5.1: 200 OK (0.014s)
# get https://goproxy.cn/sumdb/sum.golang.org/tile/8/0/x079/736
# get https://goproxy.cn/sumdb/sum.golang.org/tile/8/0/x079/736: 200 OK (0.016s)
# get https://goproxy.cn/sumdb/sum.golang.org/tile/8/0/x068/334
# get https://goproxy.cn/sumdb/sum.golang.org/tile/8/1/266
# get https://goproxy.cn/sumdb/sum.golang.org/tile/8/0/x068/334: 200 OK (0.023s)
# get https://goproxy.cn/sumdb/sum.golang.org/tile/8/1/266: 200 OK (0.028s)
go: downloading github.com/spf13/cast v1.5.1
# get https://goproxy.cn/github.com/spf13/cast/@v/v1.5.1.zip
# get https://goproxy.cn/github.com/spf13/cast/@v/v1.5.1.zip: 200 OK (0.024s)
go: added github.com/spf13/cast v1.5.1L'utilisation d'un proxy de module peut efficacement améliorer la vitesse de téléchargement des modules, pour les utilisateurs en Chine, sans proxy, ils ne peuvent généralement pas accéder au proxy officiel par défaut, voici les proxies de modules tiers publics et fiables actuellement disponibles
https://proxy.golang.com.cn, open-source et fournit également des services d'entreprisehttps://goproxy.cn, fourni et open-source par Qiniu Cloud
Il existe également des solutions de proxy de module auto-hébergées open-source : goproxy
GOSUMDB
GOSUMDB est utilisé pour définir l'adresse de la base de données de détection de somme de contrôle des bibliothèques de dépendances, par défaut sum.golang.org, lorsque vous définissez un proxy, go accédera à la base de données de somme de contrôle via le proxy.
GOPRIVATE
La variable d'environnement GOPRIVATE est utilisée pour définir les bibliothèques privées, les bibliothèques correspondantes ne seront pas vérifiées via sumdb, et n'utiliseront pas de proxy, les dépendances seront téléchargées directement via VCS. Elle prend en charge les paramètres de caractères génériques, séparés par des virgules, comme illustré ci-dessous, toutes les dépendances avec le suffixe corp.example.com et nommées github.com/gohper/myproject n'utiliseront pas de proxy ni sumdb.
GOPRIVATE=*.corp.example.com,github.com/gohper/myprojectVous pouvez également définir directement un utilisateur ou une organisation
GOPRIVATE=github.com/gopher,github.com/myorganizationGONOPROXY
Indique quelles dépendances n'ont pas besoin d'utiliser de proxy, les règles sont les mêmes que GOPRIVATE, et remplacent GOPRIVATE.
GONOSUMDB
Indique quelles dépendances n'ont pas besoin d'utiliser la base de données de somme de contrôle, les règles sont les mêmes que GOPRIVATE, et remplacent GOPRIVATE.
GOINSECURE
Indique quelles dépendances doivent être téléchargées directement via VCS, les règles sont les mêmes que GOPRIVATE, et sont remplacées par GONOPROXY et GONOSUMDB.
GOVCS
Définit le système de contrôle de version pour la gestion des modules, par défaut public:git|hg,private:all. Peut également limiter les VCS pour des noms de domaine spécifiés, par exemple
GOVCS=github.com:git,evil.com:off,*:git|hgDans les restrictions ci-dessus, github ne peut utiliser que git, evil.com n'est pas autorisé, utilisez | pour représenter plusieurs VCS. Si vous ne faites aucune restriction, vous pouvez définir comme suit
GOVCS=*:allSi vous ne permettez l'utilisation d'aucun VCS, vous pouvez définir comme suit
GOVCS=*:offGOWORK
Définit si l'espace de travail est activé, par défaut vide c'est-à-dire activé, si défini sur off, il n'est pas activé, et ignorera tous les fichiers go.work.
GOTOOLDIR
Définit l'emplacement de la chaîne d'outils go à utiliser, par défaut $GOROOT/pkg/tool, la chaîne d'outils par défaut est également stockée à cet emplacement.
GODEBUG
Définit les options de débogage, contrôle certains comportements d'exécution des programmes go sous forme de paires clé-valeur, par exemple
GODEBUG=http2client=0,http2server=0Ces paramètres sont destinés à faciliter le retour aux anciens comportements de go en cas de changements incompatibles lors des mises à jour de version, par exemple dans 1.21, panic(nil) n'est plus autorisé, pour cette raison, go officiel a spécialement enregistré GODEBUG History, consultez GODEBUG pour plus de détails.
CGO_ENABLED
Indique si cgo est activé, par défaut 1, c'est-à-dire activé, défini sur 0 pour désactiver.
Les variables d'environnement ci-dessus sont les plus couramment utilisées, pour certaines moins couramment utilisées comme CGO, WASM, etc., si vous êtes intéressé, vous pouvez les explorer vous-même.
build
Go prend en charge deux types de compilateurs, gccgo et gc. gcc est un ancien compilateur c/c++, prend en charge plusieurs langages dont go, ce dernier gc ne signifie pas garbage collection, il signifie go compiler, le langage go a terminé son auto-hébergement en go1.5, gc est un compilateur entièrement écrit en langage go, son code source est situé dans le package cmd/compile, comme il est entièrement implémenté en langage go, il est donc très pratique pour comprendre et apprendre son mécanisme interne. Par défaut, le compilateur utilise gc pour compiler. Soit dit en passant, le débogueur go existe également en deux versions, gdb et dlv, le premier est un ancien débogueur c/c++, prend en charge plusieurs langages dont go, le second est un débogueur écrit en langage go, plus convivial pour le langage go, il est également open-source, il est recommandé d'utiliser ce dernier. La commande build sert à compiler les fichiers source go en fichiers binaires exécutables, vous ferez l'expérience d'une compilation très rapide, ce qui est l'une des caractéristiques du langage go.
$ go build -h
usage: go build [-o output] [build flags] [packages]
Run 'go help build' for details.Elle accepte trois paramètres, l'un est le chemin de sortie du fichier indiqué par le drapeau -o, l'autre est les drapeaux de construction build flags utilisés pour définir le comportement de compilation, et le dernier est le package à compiler, ce paramètre doit être placé en dernier. Voici un exemple simple, sans utiliser de drapeaux de construction.
# Windows
$ go build -o .\bin\golearn.exe golearn
# macOS / Linux
$ go build -o ./bin/golearn golearn./bin/golearn.exe représente le chemin de sortie, golearn représente le module à compiler, cela peut également être un fichier d'entrée ou un répertoire. Voici un exemple simple avec le fichier d'entrée main.go comme cible de compilation.
# Windows
$ go build -o .\bin\golearn.exe main.go
# macOS / Linux
$ go build -o ./bin/golearn main.goLors de la compilation, il ignore tous les fichiers se terminant par _test.go, car ces fichiers sont par convention des fichiers de test.
En outre, la commande build prend également en charge un nombre considérable de drapeaux de construction pour contrôler certains comportements lors de la compilation.
-x: Affiche les instructions détaillées du processus de compilation-n: Similaire à-x, mais la différence est qu'elle affiche uniquement ces instructions, mais ne les exécute pas réellement.-v: Affiche les packages compilés-p: Le nombre de processus simultanés pendant la compilation-a: Force la reconstruction, même si elle est déjà à jour.-compiler: Spécifie quel compilateur utiliser,gccgoougc, ce dernier est un compilateur écrit en go.-race: Active la détection de course-msan: Active l'analyse de mémoire-asan: Active l'analyse d'adresse-cover: Active la détection de couverture de code-buildmode: Spécifie le mode de compilation, avec les optionsarchive,c-archive,c-shared,default,shared,exe,pie,plugin.-pgo, spécifie le fichier pgo-trimpath: Élimine le préfixe de chemin des fichiers source, par exemple le chemin relatif/var/lib/go/src/main.go, après élimination, le nom de fichier obtenu viaruntimelors de l'exécution n'est que le chemin relatif par rapport au chemin du module/main.go, après avoir activé cette option, le temps de compilation augmentera considérablement, d'environ 20-40%, selon le nombre de fichiers.-toolexec, certaines commandes go exécutées avant la compilation, au format-toolexec 'cmd args'.-gcflags: Spécifie certains tags du compilateur gc-gccgoflags: Spécifie certains tags du compilateur gccgo-ldflags: Spécifie certains tags de l'outil link
Pour certains paramètres de transmission comme ldflags, vous pouvez transmettre des paramètres comme "-help" pour obtenir leurs valeurs possibles, par exemple
$ go build -ldflags -help
usage: link [options] main.o
-B note
add an ELF NT_GNU_BUILD_ID note when using ELF
-E entry
set entry symbol name
......Ce qui précède sont les plus couramment utilisés, pour d'autres moins couramment utilisés, vous pouvez les explorer vous-même.
gcflags
Via gcflags, vous pouvez transmettre certains paramètres au compilateur gc pour contrôler des comportements spécifiques, son format d'utilisation est -gcflags="pattern=args list", args list est la liste des paramètres, pattern est la portée d'application, il y a les valeurs disponibles suivantes
main, le chemin du package de premier niveau où se trouve le fichier d'entréeall, le module actuel et toutes les dépendances du mode actuelstd, la bibliothèque standardcmd, agit sur tous les fichiers source du packagecmd- Caractères génériques, comme
.,./...,cmd/....
La règle pattern s'applique à tous les drapeaux qui prennent en charge ce format, comme ldflags. Utilisez la commande suivante pour afficher les valeurs disponibles des paramètres
$ go build -gcflags -help
用法:compile [选项] file.go...
-% 调试非静态初始化器
-+ 编译运行时
-B 禁用边界检查
-C 禁用错误消息中的列号打印
-D path
设置本地导入的相对路径
-E 调试符号导出
-I directory
添加目录到导入搜索路径
-K 调试缺失的行号
-L 对于受 //line 指令影响的错误位置,同时显示实际源文件名
-N 禁用优化
-S 打印汇编列表
-V 打印版本并退出
-W 类型检查后调试解析树
......Voici quelques paramètres couramment utilisés
-S: Affiche la forme assembleur du code-N: Désactive l'optimisation de compilation-m: Affiche les décisions d'optimisation-l: Désactive l'inlining de fonction-c: Le nombre de processus simultanés de compilation-dwarf: Génère des symboles DWARF
Par exemple, si vous souhaitez afficher la forme assembleur du code, vous pouvez utiliser le paramètre -S, et vous devez également désactiver l'optimisation et l'inlining, afin de restaurer sa forme originale, comme suit
$ go build -trimpath -gcflags="-N -l -S" main.go
main.main STEXT size=171 args=0x0 locals=0x58 funcid=0x0 align=0x0
0x0000 00000 (./main.go:9) TEXT main.main(SB), ABIInternal, $88-0
0x0000 00000 (./main.go:9) CMPQ SP, 16(R14)
0x0004 00004 (./main.go:9) PCDATA $0, $-2
0x0004 00004 (./main.go:9) JLS 161
0x000a 00010 (./main.go:9) PCDATA $0, $-1
0x000a 00010 (./main.go:9) PUSHQ BP
0x000b 00011 (./main.go:9) MOVQ SP, BP
0x000e 00014 (./main.go:9) SUBQ $80, SP
0x0012 00018 (./main.go:9) FUNCDATA $0, gclocals·J5F+7Qw7O7ve2QcWC7DpeQ==(SB)
0x0012 00018 (./main.go:9) FUNCDATA $1, gclocals·bDfKCdmtOiGIuJz/x+yQyQ==(SB)
0x0012 00018 (./main.go:9) FUNCDATA $2, main.main.stkobj(SB)
0x0012 00018 (./main.go:10) MOVUPS X15, main..autotmp_0+40(SP)
0x0018 00024 (./main.go:10) LEAQ main..autotmp_0+40(SP), CX
0x001d 00029 (./main.go:10) MOVQ CX, main..autotmp_2+32(SP)ldflags
Via ldflags, vous pouvez transmettre certains paramètres à l'éditeur de liens pour contrôler des comportements spécifiques, utilisez la commande suivante pour afficher toutes les valeurs disponibles de ldflags, près d'une vingtaine.
$ go build -ldflags -help
usage: link [options] main.o
-B note
add an ELF NT_GNU_BUILD_ID note when using ELF
-E entry
set entry symbol name
-H type
set header type
-I linker
use linker as ELF dynamic linker
-L directory
add specified directory to library path
-R quantum
set address rounding quantum (default -1)
-T int
set the start address of text symbols (default -1)
-V print version and exit
-X definition
add string value definition of the form importpath.name=value
-a no-op (deprecated)
.....Le paramètre -X de ldflags est une fonctionnalité très pratique, il permet de définir la valeur des variables de type chaîne d'un package spécifié lors de l'édition de liens. Grâce à cette fonctionnalité, nous pouvons facilement injecter des métadonnées lors de la compilation. Et comme ce n'est qu'une variable, il est également pratique de l'obtenir lors de l'exécution, voici un exemple simple.
package main
import "fmt"
var (
Version string
)
func main() {
fmt.Println(Version)
}Exécutez la commande
go build -ldflags "-X main.Version=$(git describe --always)" main.goAprès l'exécution, la somme de contrôle sha1 du commit git sera affichée.
5e3fd7aD'autres paramètres plus pratiques incluent
-w: Ne génère pas DWARF, qui est une information pratique pour déboguer le code source.-s: Désactive la table des symboles
Ces deux derniers sont généralement utilisés ensemble, ce qui peut réduire considérablement la taille du fichier binaire compilé, d'environ 40%-50%, l'inconvénient est également évident, impossible de déboguer, voici un exemple.
$ go build -ldflags="-w -s" main.goCompilation croisée
La compilation du langage go a deux caractéristiques principales, la première est la rapidité, l'autre grande caractéristique est la compilation croisée, la compilation croisée signifie qu'il est possible de compiler localement en code cible d'autres systèmes, par exemple compiler sur windows en fichier binaire pour linux ou darwin, et vice versa. La compilation croisée prend en charge un très grand nombre de langages, ce n'est pas quelque chose de rare, mais la compilation croisée du langage go est très simple, il suffit des étapes suivantes
- Définir la variable d'environnement GOOS, choisir votre système d'exploitation cible
- Définir la variable d'environnement GOARCH, choisir votre architecture CPU cible
- Utiliser
go buildcomme d'habitude pour compiler
L'ensemble du processus est très court, pas besoin d'utiliser d'outils ou de configurations supplémentaires, et la vitesse est aussi rapide que d'habitude. Comme illustré ci-dessous
build_linux:
SET CGO_ENABLED=0
SET GOOS="linux"
SET GOARCH="amd64"
go build -o golearn main.go
build_mac:
SET CGO_ENABLED=0
SET GOOS="darwin"
SET GOARCH="amd64"
go build -o golearn main.go
build_win:
SET CGO_ENABLED=0
SET GOOS="win"
SET GOARCH="amd64"
go build -o golearn.exe main.go
.PHONY: build_linux \
build_mac \
build_winLa première étape SET CGO_ENABLED=0 désactive cgo, une fois que votre code utilise cgo, alors la compilation croisée ne peut pas être utilisée normalement. La deuxième étape SET GOOS définit le système cible, les options disponibles sont linux, darwin, windows, netbsd. La troisième étape définit l'architecture CPU, SET GOARCH, les options disponibles sont amd64, 386, arm, ppc64. La dernière étape consiste à compiler comme d'habitude.
Contrôle de compilation
La commande build peut atteindre le contrôle de compilation via tags, qui existe dans le code source sous forme d'instructions, prenons un exemple, le fichier product.go
// +build product
package main
import "fmt"
func main() {
fmt.Println("product")
}Le fichier debug.go
// +build debug
package main
import "fmt"
func main() {
fmt.Println("debug")
}Ils ont tous une instruction // +build, qui indique dans quelles conditions ils seront compilés. Le format de base est
// +build tag1 tag2
package pkg_nameIl y a plusieurs règles à respecter
//et+builddoivent être séparés par un espace- Il doit être situé au-dessus de la déclaration du package
- Doit être séparé de la déclaration du package par une ligne vide
En outre, il peut également atteindre le contrôle logique via de simples espacements, l'espace représente OR, la virgule représente AND, ! représente NOT. Par exemple
// +build windows linux
package pkg_nameSignifie que le fichier actuel sera compilé sous les plateformes windows ou linux.
// +build windows,amd64,!cgo linux,i386,cgo
package pkg_nameCet exemple signifie qu'il sera compilé uniquement sous la plateforme windows architecture amd64 et sans cgo activé, ou sous la plateforme linux architecture i386 et avec cgo activé. Si vous ne voulez tout simplement pas qu'un fichier participe à la compilation, vous pouvez utiliser ignore.
// +build ignore
package pkg_nameIl peut également y avoir des instructions sur plusieurs lignes
// +build windows
// +build amd64
package pkg_nameLes instructions sur plusieurs lignes sont traitées de manière AND. Pour les tags de plateforme et d'architecture, go les transmet automatiquement lors de la compilation, nous pouvons également transmettre des tags personnalisés, prenons les deux fichiers du début comme exemple
$ go build -tags="debug" . && ./golearn.exe
debug
$ go build -tags="product" . && ./golearn.exe
productVous pouvez voir que la sortie est différente lorsque différents tags sont transmis, l'objectif du contrôle de compilation est ainsi atteint.
run
Les commandes run et build compilent toutes deux le code source, la différence est que la commande run s'exécute directement après la compilation. La commande run, afin d'accélérer la vitesse de compilation, ne génère pas d'informations de débogage pendant le processus de compilation, donc ne prend pas en charge le débogage, et génère uniquement un fichier binaire temporaire, généralement stocké dans le répertoire GOTMPDIR, par exemple /temp/go-build2822241271/b001/exe/main.exe.
$ go run -h
usage: go run [build flags] [-exec xprog] package [arguments...]
Run 'go help run' for details.Elle prend également en charge les drapeaux de construction de la commande build, et fournit également un paramètre -exec pour indiquer quel programme utiliser pour exécuter le fichier binaire, [arguments...] fait référence aux paramètres d'exécution du programme. Voici un exemple
package main
import (
"fmt"
"os"
)
var (
Version string
)
func main() {
fmt.Println(Version)
fmt.Println(os.Args[1:])
}Exécuter avec go run
$ go run -ldflags="-X main.Version=$(git describe --always)" main.go hello
5e3fd7a
[hello]Dans l'ensemble, l'utilisation n'est pas très différente de go build, donc je ne vais pas trop m'étendre.
tool
La commande tool n'a aucune fonction en soi, son rôle est d'appeler directement les outils du répertoire cmd/, par exemple cmd/compile est le compilateur intégré. Via go tool, vous pouvez appeler directement ces outils, sans avoir à exécuter manuellement les fichiers binaires de ces outils.
$ go tool -h
usage: go tool [-n] command [args...]Utiliser le paramètre -n pour afficher tous les paramètres de commande pris en charge
$ go tool -n
addr2line
asm
buildid
cgo
compile
covdata
cover
doc
fix
link
nm
objdump
pack
pprof
test2json
trace
vetCes outils sont stockés dans le répertoire GOROOT/pkg/tool, et sont regroupés en fonction du système d'exploitation et de l'architecture CPU, comme suit.
$ ls $GOROOT/pkg/tool/windows_amd64/ -1
addr2line.exe*
asm.exe*
buildid.exe*
cgo.exe*
compile.exe*
covdata.exe*
cover.exe*
doc.exe*
fix.exe*
link.exe*
nm.exe*
objdump.exe*
pack.exe*
pprof.exe*
test2json.exe*
trace.exe*
vet.exe*Utilisez le format go doc cmd/command pour afficher l'utilisation de chaque commande, par exemple
$ go doc cmd/compile
Usage:
go tool compile [flags] file...
The specified files must be Go source files and all part of the same package.
The same compiler is used for all target operating systems and architectures.
The GOOS and GOARCH environment variables set the desired target.
Flags:
-D path
Set relative path for local imports.
-I dir1 -I dir2
Search for imported packages in dir1, dir2, etc,
after consulting $GOROOT/pkg/$GOOS_$GOARCH.
-L
Show complete file path in error messages.
...Les paramètres de drapeau pris en charge par cmd/compile sont les mêmes que ceux pris en charge par gcflags mentionnés précédemment. La différence entre go tool compile et go build est que le premier est uniquement responsable de la compilation, et ne peut prendre que des fichiers comme paramètres, le second peut prendre des répertoires, des packages, des fichiers comme paramètres, et ne fait pas que compiler le code source, il est également responsable de la liaison des fichiers, de la suppression des fichiers inutiles, etc., le premier fait partie du second. Nous pouvons afficher les commandes exécutées pendant le processus build
$ go build -n main.go
#
# internal/goarch
#
mkdir -p $WORK\b004\
cat >$WORK\b004\importcfg << 'EOF' # internal
# import config
EOF
"/golang/pkg/tool/windows_amd64/compile.exe" -o "$WORK/b004/_pkg_.a" -trimpath "$WORK/b004=>" -p internal/goarch -std -+ -complete -buildid 3gunEkUExGdhOPa2rFsh/3gunEkUExGdhOPa2rFsh -goversion go1.21.0 -c=4 -nolocalimports -importcfg "$WORK/b004/importcfg" -pack "/golang/src/internal/goarch/goarch.go" "/golang/src/internal/goarch/goarch_amd64.go" "/golang/src/internal/goarch/zgoarch_amd64.go"
"/golang/pkg/tool/windows_amd64/buildid.exe" -w "$WORK/b004/_pkg_.a" # internal
...Dans le processus, vous pouvez voir qu'il y a /golang/pkg/tool/windows_amd64/compile.exe, qui appelle le compilateur. En plus de compile, il y a beaucoup d'autres outils qui peuvent être appelés, beaucoup de commandes go sont en fait leurs alias.
clean
La commande clean est utilisée pour supprimer les fichiers objets générés pendant le processus de compilation
$ go clean -h
usage: go clean [clean flags] [build flags] [packages]
Run 'go help clean' for details.Elle prend en charge les drapeaux suivants
-i: Supprime les fichiers archive ou binaires correspondants-n: Affiche les commandes à exécuter pour le processus de nettoyage mais ne les exécute pas réellement-x: Affiche les commandes à exécuter pour le processus de nettoyage et les exécute-r: Nettoie récursivement viaimport path-cache, supprime tout le cache généré pargo build-testcache: Supprime tout le cache de test généré-modcache: Supprime tout le cache de modules téléchargés-fuzzcache: Supprime le cache généré parfuzz test.
Lors de l'utilisation de go tool compile, c'est un appel direct à la commande du compilateur, et ne fait pas beaucoup de traitement postérieur comme go build, ce qui génère des fichiers objets. Par exemple, exécutez la commande suivante
go tool compile -N -S -l main.goCela générera un fichier nommé main.o, utilisez la commande go clean pour le supprimer. Ou utilisez le paramètre -n pour afficher les commandes à exécuter.
$ go clean -n
rm -f golearn golearn.exe golearn golearn.exe golearn.test golearn.test.exe golearn.test golearn.test.exe api api.exe main main.exeSupprime le cache de compilation, il supprimera le cache de compilation généré dans le répertoire GOCACHE
$ go clean -cache -n
rm -r /cache/00 /cache/01 /cache/02Supprime le cache généré par fuzz test, ces caches sont stockés par défaut dans le répertoire GOCACHE/fuzz/
$ go clean -fuzzcache -n
rm -rf /cache/fuzzfix
Le langage go a maintenant dix ans depuis la rédaction de cet article, dans le processus de mise à jour et de modification continue du langage, il est inévitable qu'il y ait des incompatibilités dues aux changements d'API, la commande fix est conçue pour cela, elle détecte les API obsolètes dans les fichiers source et les remplace par de nouvelles API.
$ go fix -h
usage: go fix [-fix list] [packages]
Run 'go help fix' for details.Elle prend en charge les répertoires, les noms de fichiers, les répertoires comme paramètres, accepte le drapeau -fix pour transmettre des paramètres afin d'indiquer quel type de modification effectuer, vous pouvez utiliser la commande go tool fix -help pour afficher les valeurs disponibles
$ go tool fix -help
usage: go tool fix [-diff] [-r fixname,...] [-force fixname,...] [path ...]
-diff
display diffs instead of rewriting files
-force string
force these fixes to run even if the code looks updated
-go string
go language version for files
-r string
restrict the rewrites to this comma-separated list
Available rewrites are:
buildtag
Remove +build comments from modules using Go 1.18 or later
cftype
Fixes initializers and casts of C.*Ref and JNI types
context
Change imports of golang.org/x/net/context to context
egl
Fixes initializers of EGLDisplay
eglconf
Fixes initializers of EGLConfig
gotypes
Change imports of golang.org/x/tools/go/{exact,types} to go/{constant,types}
jni
Fixes initializers of JNI's jobject and subtypes
netipv6zone
Adapt element key to IPAddr, UDPAddr or TCPAddr composite literals.
https://codereview.appspot.com/6849045/
printerconfig
Add element keys to Config composite literals.Voici un exemple, le code source utilise le package golang.org/x/net/context
package main
import (
"fmt"
"golang.org/x/net/context"
)
func main() {
background := context.Background()
fmt.Println(background.Err())
}Utilisez go fix pour corriger, en le remplaçant par le package context de la bibliothèque standard, vous pouvez utiliser la commande suivante pour effectuer le remplacement
$ go fix -fix context main.goVous pouvez également ne pas remplacer, et voir les changements de fichier avant et après.
$ go tool fix -r context -diff main.go
main.go: fixed context
diff main.go fixed/main.go
--- main.go
+++ fixed/main.go
@@ -1,8 +1,8 @@
package main
import (
+ "context"
"fmt"
- "golang.org/x/net/context"
)
func main() {Le langage go existe depuis plus de dix ans et n'a que neuf paramètres de remplacement disponibles, ce qui montre que la compatibilité est plutôt bien maintenue.
fmt
La commande fmt est l'outil de formatage intégré de go, utilisé pour formater les fichiers source go.
$ go fmt -h
usage: go fmt [-n] [-x] [packages]
Run 'go help fmt' for details.Utilisez la commande go doc gofmt pour afficher sa documentation détaillée
$ go doc cmd/gofmt
Gofmt formats Go programs. It uses tabs for indentation and blanks for
alignment. Alignment assumes that an editor is using a fixed-width font.
Usage:
gofmt [flags] [path ...]
The flags are:
-d
Do not print reformatted sources to standard output.
If a file's formatting is different than gofmt's, print diffs
to standard output.
-e
Print all (including spurious) errors.
-l
Do not print reformatted sources to standard output.
If a file's formatting is different from gofmt's, print its name
to standard output.
-r rule
Apply the rewrite rule to the source before reformatting.
-s
Try to simplify code (after applying the rewrite rule, if any).
-w
Do not print reformatted sources to standard output.
If a file's formatting is different from gofmt's, overwrite it
with gofmt's version. If an error occurred during overwriting,
the original file is restored from an automatic backup.gofmt utilise des tab pour l'indentation, des espaces pour l'alignement, par défaut le code formaté sera affiché sur la sortie standard, et non écrasé sur le fichier original. La commande go fmt utilise en fait la commande gofmt, qui est un fichier binaire indépendant, situé dans le répertoire GOROOT/bin.
$ ls $GOROOT/bin -1
go.exe*
gofmt.exe*Ajoutez le drapeau -n à la commande go fmt pour savoir quelles commandes seront exécutées.
$ go fmt main.go
/golang/bin/gofmt.exe -l -w main.goOn peut voir que go fmt est en fait un alias de gofmt -l -w, la commande gofmt dispose des paramètres suivants
-d: Affiche les différences de fichier avant et après le formatage-e: Affiche toutes les erreurs-l: Affiche les noms de fichiers qui ont été modifiés-r: Applique les règles de formatage-s: Tente de simplifier le code-w: Écrase le fichier source, restaure la sauvegarde en cas d'erreur
Supposons maintenant que nous ayons le fichier source suivant
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("hello world!")}Utilisez le paramètre -d pour prévisualiser les changements
$ gofmt -d main.go
diff main.go.orig main.go
--- main.go.orig
+++ main.go
@@ -3,5 +3,5 @@
import "fmt"
func main() {
-fmt.Println("hello world!")}
-
+ fmt.Println("hello world!")
+}Le paramètre -l affichera les noms de fichiers qui seront modifiés
$ gofmt -l .
main.goS'il y a des erreurs de syntaxe, le paramètre -e peut afficher plus de détails
$ gofmt -d -e main.go
main.go:6:27: missing ',' in argument list
main.go:6:28: expected operand, found newline
main.go:7:2: expected ')', found 'EOF'
main.go:7:2: expected ';', found 'EOF'
main.go:7:2: expected ';', found 'EOF'
main.go:7:2: expected '}', found 'EOF'
main.go:7:2: missing ',' in argument list-w appliquera les modifications au fichier source
$ gofmt -l -w .
main.go
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("hello world!")
}Vous pouvez constater qu'en tant qu'outil de formatage, gofmt ne fournit aucune configuration personnalisée, tandis que le formateur prettify dédié à l'embellissement du code js fournit un nombre considérable de configurations pour formater le code, cela reflète l'attitude de go officiel, ne voulez pas de personnalisation, le style de code de tout le monde ferait mieux d'être cohérent, au moins il y a un avantage, c'est que vous n'avez pas à vous adapter aux habitudes des autres lors de la lecture de code. Mais en fait, il conserve toujours un élément personnalisable, qui est les règles de remplacement du code formaté, les règles peuvent être personnalisées, le format est le suivant
pattern -> replacementPar exemple, supprimer les parenthèses redondantes
(a) -> aAfficher les changements de fichier
$ gofmt -r "(a) -> a" -d -l .
main.go
diff main.go.orig main.go
--- main.go.orig
+++ main.go
@@ -3,5 +3,5 @@
import "fmt"
func main() {
- fmt.Println(("hello world!"))
+ fmt.Println("hello world!")
}Vous pouvez voir que gofmt supprimera les parenthèses redondantes.
get
La commande get est absolument la plus couramment utilisée dans le développement go, son rôle est de télécharger le code source du package spécifié dans le répertoire correspondant à GOMODCACHE.
$ go get -h
usage: go get [-t] [-u] [-v] [build flags] [packages]
Run 'go help get' for details.-u: Tente de mettre à jour les versions mineures et les versions de correctifs du package, si cela implique un changement de version majeure, commev1->v2, ne sera pas mis à jour.-t: Met à jour les versions des dépendances dans les tests-v: Affiche les packages compilés, fait en fait partie des paramètres debuild flags
Dans les temps anciens, go get avait un rôle similaire à go install, il téléchargeait et compilait ces packages, cependant avec la naissance et l'amélioration des modules go, cette partie du rôle a progressivement été abandonnée, la commande get est maintenant le plus souvent utilisée pour télécharger et résoudre les dépendances des modules go, donc vous pouvez voir que la commande go get prend également en charge les drapeaux de construction de type build flags, et si vous essayez d'utiliser go get en dehors d'un module comme vous utiliseriez go install, il vous indiquera que cette utilisation est obsolète.
$ go get github.com/wire/wire
go: go.mod file not found in current directory or any parent directory.
'go get' is no longer supported outside a module.
To build and install a command, use 'go install' with a version,
like 'go install example.com/cmd@latest'
For more information, see https://golang.org/doc/go-get-install-deprecation
or run 'go help get' or 'go help install'.Pourquoi ces descriptions sont conservées dans la documentation est inconnu, en parcourant le code source de la commande get, vous découvrirez également qu'elle conserve les anciens drapeaux.
var (
getD = CmdGet.Flag.Bool("d", true, "")
getF = CmdGet.Flag.Bool("f", false, "")
getFix = CmdGet.Flag.Bool("fix", false, "")
getM = CmdGet.Flag.Bool("m", false, "")
getT = CmdGet.Flag.Bool("t", false, "")
getU upgradeFlag
getInsecure = CmdGet.Flag.Bool("insecure", false, "")
// -v is cfg.BuildV
)Pour en revenir au sujet, la commande get téléchargera le code source du package spécifié dans le répertoire de dépendances global local, c'est-à-dire le répertoire correspondant à GOCACHE, puis enregistrera les informations dans les fichiers go.mod et go.sum, le premier est responsable de l'enregistrement de la version, le second est responsable de l'enregistrement de la somme de contrôle sha1 pour assurer la sécurité. La commande get est en fait basée sur VCS, c'est-à-dire le système de contrôle de version local, prend en charge les suivants au total
- git
- hg (Mercurial)
- bzr (Bazaar)
- svn
- fossil
Parmi eux, par défaut, seuls git et hg sont pris en charge, peuvent être configurés dans GOVCS, le format est le suivant
GOVCS=github.com:git,example.com:hg,*:git|hg,*:allGOVCS prend uniquement en charge git et hg en tant que VCS, les trois autres doivent être configurés dans GOPRIVATE.
La commande go get a au total les utilisations suivantes, peut directement utiliser l'adresse de dépendance comme paramètre
$ go get golang.org/x/netPeut également spécifier une version
$ go get golang.org/x/net@0.17.0Spécifier la dernière version
$ go get golang.org/x/net@latestTenter de mettre à jour la version
$ go get -u golang.org/x/netSupprimer une dépendance
$ go get golang.org/x/net@noneCe qui précède est utilisé pour gérer les dépendances ordinaires, elle peut également être utilisée pour gérer des dépendances moins ordinaires, comme mettre à jour la version du langage go
$ go get go@latest
go: updating go.mod requires go >= 1.21.3; switching to go1.21.3
go: downloading go1.21.3 (windows/amd64)
go: upgraded go 1.21.0 => 1.21.3Peut même être utilisée pour mettre à jour la version de la chaîne d'outils go
$ go get toolchain@latestLorsque vous utilisez go get pour mettre à jour les versions de go et de la chaîne d'outils, elles installeront la nouvelle version de go dans le répertoire GOMODCACHE/golang.org/
$ ls $(go env GOMODCACHE)/golang.org -1
'toolchain@v0.0.1-go1.21.3.windows-amd64'/
x/Ensuite, modifiez manuellement GOROOT pour passer à la version spécifiée.
install
La commande install est similaire à la commande get, elles sont toutes deux utilisées pour télécharger des dépendances tierces, mais la différence est que la commande get télécharge le code source, tandis que la commande install compile le code source en un fichier binaire exécutable pour la machine locale, le chemin de stockage du fichier binaire est d'abord dans le répertoire GOBIN, puis GOPATH/bin. La fonction principale de cette commande est de télécharger des outils en ligne de commande publics tiers, grâce à la vitesse de compilation et à la portabilité du langage go, il n'est pas nécessaire de télécharger des fichiers binaires, mais de télécharger directement le code source puis de le compiler localement.
$ go install -h
usage: go install [build flags] [packages]
Run 'go help install' for details.La commande install accepte les drapeaux de construction et les noms de packages comme paramètres, avec gomod activé, le nom du package doit inclure un numéro de version. Par exemple, télécharger le débogueur delve
$ go install -x github.com/go-delve/delve/cmd/dlv@latest
# get https://goproxy.cn/github.com/@v/list
# get https://goproxy.cn/github.com/go-delve/delve/cmd/@v/list
# get https://goproxy.cn/github.com/go-delve/delve/cmd/dlv/@v/list
# get https://goproxy.cn/github.com/go-delve/delve/@v/list
# get https://goproxy.cn/github.com/go-delve/@v/list
# get https://goproxy.cn/github.com/@v/list: 404 Not Found (0.014s)
# get https://goproxy.cn/github.com/go-delve/delve/cmd/@v/list: 404 Not Found (0.027s)
# get https://goproxy.cn/github.com/go-delve/delve/cmd/dlv/@v/list: 404 Not Found (0.027s)
# get https://goproxy.cn/github.com/go-delve/delve/@v/list: 200 OK (0.027s)
# get https://goproxy.cn/github.com/go-delve/@v/list: 404 Not Found (0.027s)
WORK=/home/user/tmp/go-build2033992495
mkdir -p $WORK/b001/
cat >/home/user/tmp/go-build2033992495/b001/importcfg.link << 'EOF' # internal
packagefile github.com/go-delve/delve/cmd/dlv=/home/user/.cache/go-build/f1/f11d552287458c0fce625abe50bf928c487064c36bbb1251ad8b1968772c3e4b-d
......
......
mkdir -p /home/wyh/gomod/bin/
mv $WORK/b001/exe/a.out /home/wyh/gomod/bin/dlv
rm -r $WORK/b001/Elle téléchargera d'abord le code source dans le chemin de stockage de GOMODCACHE, ce qui est cohérent avec la commande get, puis passera au répertoire de travail temporaire, le compilera, après la compilation, déplacera le fichier binaire dans le répertoire GOPATH/bin, et enfin supprimera le répertoire temporaire. La commande install a également une limitation, c'est que le package téléchargé doit être le package d'entrée du projet, c'est-à-dire qu'il doit contenir le fichier d'entrée main.go, sinon il vous indiquera qu'il ne peut pas être installé. Par exemple, utilisez go install pour télécharger gin
$ go install -x github.com/gin-gonic/gin@latest
# get https://goproxy.cn/github.com/@v/list
# get https://goproxy.cn/github.com/gin-gonic/gin/@v/list
# get https://goproxy.cn/github.com/gin-gonic/@v/list
# get https://goproxy.cn/github.com/@v/list: 404 Not Found (0.022s)
# get https://goproxy.cn/github.com/gin-gonic/gin/@v/list: 200 OK (0.027s)
# get https://goproxy.cn/github.com/gin-gonic/@v/list: 404 Not Found (0.028s)
package github.com/gin-gonic/gin is not a main packagegin est une bibliothèque de dépendances de framework web, ce n'est pas un outil en ligne de commande, donc naturellement il n'y a pas de fichier d'entrée, donc l'installation échouera.
list
La commande list liste les packages à l'emplacement spécifié, un par ligne, et prend en charge la sortie formatée personnalisée, prend en charge de nombreux paramètres, la condition préalable à son utilisation est qu'elle doit être dans un projet qui prend en charge gomod.
$ go list -h
usage: go list [-f format] [-json] [-m] [list flags] [build flags] [packages]
Run 'go help list' for details.Les paramètres qu'elle prend en charge sont les suivants
-f: Paramètre de formatage-json: Sortie au format json-compiled: Affiche tous les packages qui seront compilés par le compilateur-deps: Affiche chaque package et le nom de chaque package dont il dépend-test: Affiche le package de test de chaque package-e: Affiche normalement lors de la rencontre de packages erronés-find: N'analyse pas les relations de dépendance de ces packages-export: Lors de l'utilisation de ce paramètre, définit la valeur du champPackage.Exportde la structure sur le fichier contenant les informations d'exportation les plus récentes du package spécifié, et définit la valeur du champPackage.BuildIDsur leBuildIDdu package, principalement utilisé pour la sortie formatée.
Paramètres d'informations de module,
-m: Affiche les modules au lieu des packages-versions: Affiche toutes les informations disponibles d'un module-retracted: Affiche les versions retirées d'un module
Le paramètre [packages] peut être un nom de package spécifié, ou un répertoire, ou all, qui signifie n'importe où, lors de l'utilisation du paramètre -m, all signifie toutes les dépendances référencées par le module actuel.
Par exemple, le fichier actuel contient uniquement un fichier main.go, et contient uniquement une ligne de code qui affiche "hello world", après l'exécution de go list -deps ., il affiche tous les packages dépendants depuis le projet actuel jusqu'à fmt et ses références.
$ ls
go.mod go.sum main.go
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
$ go list -deps .
internal/goarch
unsafe
internal/abi
internal/unsafeheader
internal/cpu
internal/bytealg
internal/coverage/rtcov
internal/godebugs
internal/goexperiment
internal/goos
runtime/internal/atomic
runtime/internal/math
runtime/internal/sys
runtime
......
......
path
io/fs
os
fmt
golearnOu affiche toutes les dépendances de module du projet actuel
$ go list -m all
golearn
cloud.google.com/go v0.26.0
github.com/246859/containers v0.0.1
github.com/246859/river v0.1.0 => D:\WorkSpace\Code\riverdb
github.com/BurntSushi/toml v0.3.1
github.com/Jleagle/steam-go v0.0.0-20230725082712-1053b441b1f2
github.com/Jleagle/unmarshal-go v0.0.0-20210227002040-694f544f9265
github.com/KyleBanks/depth v1.2.1
github.com/Microsoft/go-winio v0.6.1
github.com/PuerkitoBio/purell v1.1.1
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578
github.com/andeya/ameda v1.5.3
github.com/andeya/goutil v1.0.1
...format
La sortie de la commande list est par ligne, chaque ligne de sortie est un package. L'officiel fournit un paramètre -f qui nous permet de personnaliser le format de sortie de ligne, la valeur qu'il accepte est la syntaxe de modèle définie par le package de moteur de modèle template/text, par exemple
-f "package {{ .Dir }} {{ .Name }}"Chaque package itéré sera transmis sous la forme de la structure suivante, tous les champs de cette structure peuvent être utilisés comme paramètres de modèle.
type Package struct {
Dir string // directory containing package sources
ImportPath string // import path of package in dir
ImportComment string // path in import comment on package statement
Name string // package name
Doc string // package documentation string
Target string // install path
Shlib string // the shared library that contains this package (only set when -linkshared)
Goroot bool // is this package in the Go root?
Standard bool // is this package part of the standard Go library?
Stale bool // would 'go install' do anything for this package?
StaleReason string // explanation for Stale==true
Root string // Go root or Go path dir containing this package
ConflictDir string // this directory shadows Dir in $GOPATH
BinaryOnly bool // binary-only package (no longer supported)
ForTest string // package is only for use in named test
Export string // file containing export data (when using -export)
BuildID string // build ID of the compiled package (when using -export)
Module *Module // info about package's containing module, if any (can be nil)
Match []string // command-line patterns matching this package
DepOnly bool // package is only a dependency, not explicitly listed
DefaultGODEBUG string // default GODEBUG setting, for main packages
// Source files
GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
CgoFiles []string // .go source files that import "C"
CompiledGoFiles []string // .go files presented to compiler (when using -compiled)
IgnoredGoFiles []string // .go source files ignored due to build constraints
IgnoredOtherFiles []string // non-.go source files ignored due to build constraints
CFiles []string // .c source files
CXXFiles []string // .cc, .cxx and .cpp source files
MFiles []string // .m source files
HFiles []string // .h, .hh, .hpp and .hxx source files
FFiles []string // .f, .F, .for and .f90 Fortran source files
SFiles []string // .s source files
SwigFiles []string // .swig files
SwigCXXFiles []string // .swigcxx files
SysoFiles []string // .syso object files to add to archive
TestGoFiles []string // _test.go files in package
XTestGoFiles []string // _test.go files outside package
// Embedded files
EmbedPatterns []string // //go:embed patterns
EmbedFiles []string // files matched by EmbedPatterns
TestEmbedPatterns []string // //go:embed patterns in TestGoFiles
TestEmbedFiles []string // files matched by TestEmbedPatterns
XTestEmbedPatterns []string // //go:embed patterns in XTestGoFiles
XTestEmbedFiles []string // files matched by XTestEmbedPatterns
// Cgo directives
CgoCFLAGS []string // cgo: flags for C compiler
CgoCPPFLAGS []string // cgo: flags for C preprocessor
CgoCXXFLAGS []string // cgo: flags for C++ compiler
CgoFFLAGS []string // cgo: flags for Fortran compiler
CgoLDFLAGS []string // cgo: flags for linker
CgoPkgConfig []string // cgo: pkg-config names
// Dependency information
Imports []string // import paths used by this package
ImportMap map[string]string // map from source import to ImportPath (identity entries omitted)
Deps []string // all (recursively) imported dependencies
TestImports []string // imports from TestGoFiles
XTestImports []string // imports from XTestGoFiles
// Error information
Incomplete bool // this package or a dependency has an error
Error *PackageError // error loading package
DepsErrors []*PackageError // errors loading dependencies
}
type PackageError struct {
ImportStack []string // shortest path from package named on command line to this one
Pos string // position of error (if present, file:line:col)
Err string // the error itself
}Si l'itération concerne des modules, ils seront transmis sous la forme de la structure suivante, tous ses champs peuvent également être utilisés comme paramètres de modèle.
type Module struct {
Path string // module path
Query string // version query corresponding to this version
Version string // module version
Versions []string // available module versions
Replace *Module // replaced by this module
Time *time.Time // time version was created
Update *Module // available update (with -u)
Main bool // is this the main module?
Indirect bool // module is only indirectly needed by main module
Dir string // directory holding local copy of files, if any
GoMod string // path to go.mod file describing module, if any
GoVersion string // go version used in module
Retracted []string // retraction information, if any (with -retracted or -u)
Deprecated string // deprecation message, if any (with -u)
Error *ModuleError // error loading module
Origin any // provenance of module
Reuse bool // reuse of old module info is safe
}
type ModuleError struct {
Err string // the error itself
}Afficher tous les packages
$ go list -f "package {{.Dir}} {{.Name}}" ./...
package /golearn main
package /golearn/app cmd
package /golearn/cmd cmd
package /golearn/docs docs
package /golearn/tool tool
package /golearn/tool_test toolAfficher les modules
$ go list -m -f "mod {{.Path}} {{.Version}} {{.GoVersion}} {{.GoMod}}"
mod golearn 1.21.3 /golearn/go.modmod
go mod est une commande dédiée à la gestion des modules go.
$ go mod help
Go mod provides access to operations on modules.
Note that support for modules is built into all the go commands,
not just 'go mod'. For example, day-to-day adding, removing, upgrading,
and downgrading of dependencies should be done using 'go get'.
See 'go help modules' for an overview of module functionality.
Usage:
go mod <command> [arguments]
The commands are:
download download modules to local cache
edit edit go.mod from tools or scripts
graph print module requirement graph
init initialize new module in current directory
tidy add missing and remove unused modules
vendor make vendored copy of dependencies
verify verify dependencies have expected content
why explain why packages or modules are needed
Use "go help mod <command>" for more information about a command.Elle dispose des sous-commandes suivantes
download: Télécharge toutes les dépendances indiquées dans le fichiergo.moddans le cache localedit: Modifie le fichiergo.mod, l'interface de ligne de commande fournie est principalement destinée à être appelée par d'autres outils ou scripts.init: Initialise un projet gomod dans le répertoire actueltidy: Télécharge les dépendances manquantes, supprime les dépendances inutilesgraph: Affiche le graphique des dépendancesverify: Vérifie les dépendances localeswhy: Explique pourquoi ces modules sont dépendantsvendor: Exporte les dépendances du projet vers le répertoire vendor
init
$ go help mod init
usage: go mod init [module-path]La commande init est utilisée pour initialiser un projet gomod, son seul paramètre est le chemin du module, si quelqu'un veut télécharger vos dépendances à l'avenir, il devra utiliser ce chemin de module comme base. Sa règle de nommage est généralement
domain_name/user_name/repo_namePar exemple, comme tout le monde met généralement ses projets sur github, cela peut être
github.com/jack/gotourIl est déconseillé d'utiliser des caractères spéciaux comme chemin de module. Voici un cas d'utilisation
$ mkdir gotour
$ cd gotour
$ go mod init "github.com/jack/gotour"
go: creating new go.mod: module github.com/jack/gotourtidy
$ go help mod tidy
usage: go mod tidy [-e] [-v] [-x] [-go=version] [-compat=version]La commande tidy supprimera les dépendances inutiles de go.mod, c'est-à-dire les dépendances qui ne sont pas référencées, et téléchargera les dépendances qui sont référencées mais qui n'existent pas. Elle prend en charge les paramètres suivants
-v, affiche les dépendances de module supprimées-e, ignore les erreurs si elles se produisent pendant le processus et continue l'exécution-x, affiche le processus d'exécution-go=version, met à jour la version go dans le fichiergo.mod-compat=version, conserve toutes les sommes de contrôle supplémentaires requises de la version Go principale spécifiée pour charger le graphique de modules avec succès, et si la commandegode cette version charge tout package importé à partir de différentes versions de modules, cela entraînera une erreur tidy. Ce paramètre est rarement utilisé, généralement des erreurs se produisent uniquement lors des changements de version, vous pouvez consulter cette réponse sur stackoverflow go modules - go mod tidy error message: "but go 1.16 would select" - Stack Overflow
Voici un exemple d'utilisation
$ go mod tidy -v
unused github.com/246859/containers
unused github.com/246859/river
unused github.com/Jleagle/steam-go
unused github.com/Jleagle/unmarshal-go
unused github.com/KyleBanks/depth
unused github.com/Microsoft/go-winio
unused github.com/PuerkitoBio/purell
unused github.com/PuerkitoBio/urlesc
unused github.com/andeya/ameda
unused github.com/andeya/goutil
unused github.com/asaskevich/govalidator
unused github.com/buger/jsonparser
unused github.com/bwmarrin/snowflake
unused github.com/bytedance/go-tagexpr/v2
unused github.com/bytedance/sonic
unused github.com/cespare/xxhash/v2
unused github.com/chenzhuoyu/base64x
......download
$ go help mod download
usage: go mod download [-x] [-json] [-reuse=old.json] [modules]Bien que le nom de la commande download se traduise par télécharger, elle ne fait que télécharger les dépendances dans le cache de dépendances local, ne modifie pas le fichier go.mod, son rôle est de pré-télécharger les dépendances dans le cache de fichiers local, si vous souhaitez télécharger une dépendance spécifique, il est recommandé d'utiliser go get ou go mod tidy.
Voici quelques exemples d'utilisation
$ go mod download -x gorm.io/gorm
# get https://goproxy.cn/gorm.io/gorm/@v/list
# get https://goproxy.cn/gorm.io/gorm/@v/list: 200 OK (0.084s)Sans aucun paramètre, elle téléchargera toutes les dépendances qui existent dans le fichier go.mod mais qui n'existent pas dans le cache de dépendances local, s'il n'y a rien à télécharger, elle affichera
go: no module dependencies to downloadedit
$ go help mod edit
usage: go mod edit [editing flags] [-fmt|-print|-json] [go.mod]edit est une interface de ligne de commande utilisée pour modifier le fichier go.mod, généralement fournie à d'autres programmes, certains éditeurs IDE utiliseront ces commandes pour fournir un support gomod. Elle prend en charge les paramètres suivants
-module, modifie le chemin du module-go=version, modifie la version go attendue-require=path@version, ajoute une dépendance-droprequire=path@version, supprime une dépendance-exclude=path@version, ajoute une dépendance exclue-dropexclude=path@version, supprime une dépendance exclue-replace=old@version=new@version, ajoute une dépendance de remplacement-dropreplace=old@version, supprime une dépendance de remplacement-retract=version, ajoute un élément de rétraction de version-dropretract=version, supprime un élément de rétraction de version
Il y a aussi d'autres paramètres utilisés pour l'affichage
-print, affiche le contenu du fichier-json, affiche au format json
Par exemple
$ go mod edit -print
module golearn
go 1.21.3
require (
github.com/dstgo/task v1.2.0
github.com/spf13/cast v1.5.1
github.com/swaggo/swag v1.16.2
golang.org/x/net v0.19.0
gorm.io/gorm v1.25.5
)graph
$ go help mod graph
usage: go mod graph [-go=version] [-x]La commande graph affichera le graphique des dépendances du projet actuel, sa lisibilité est très mauvaise, et la plupart du temps n'est pas destinée à être lue par des humains, les résultats sont généralement traités puis affichés sous forme visualisée. Chaque ligne est une dépendance, le format est le suivant
Référence RéférencéPar exemple
golearn go@1.21.3Elle prend également en charge deux paramètres
-go=version, charge le graphique des dépendances avec la version go donnée, sa valeur ne peut pas être inférieure à la version dans le fichiergo.mod.-x, affiche les commandes exécutées pendant le processus.
Voici un exemple d'utilisation simple
$ go mod graph
golearn github.com/246859/containers@v0.0.1
golearn github.com/246859/river@v0.1.0
golearn github.com/Jleagle/steam-go@v0.0.0-20230725082712-1053b441b1f2
golearn github.com/Jleagle/unmarshal-go@v0.0.0-20210227002040-694f544f9265
golearn github.com/KyleBanks/depth@v1.2.1
golearn github.com/Microsoft/go-winio@v0.6.1
golearn github.com/PuerkitoBio/purell@v1.1.1
golearn github.com/PuerkitoBio/urlesc@v0.0.0-20170810143723-de5bf2ad4578
golearn github.com/andeya/ameda@v1.5.3
golearn github.com/andeya/goutil@v1.0.1
golearn github.com/asaskevich/govalidator@v0.0.0-20230301143203-a9d515a09cc2
golearn github.com/buger/jsonparser@v1.1.1
golearn github.com/bwmarrin/snowflake@v0.3.0
golearn github.com/bytedance/go-tagexpr/v2@v2.9.11
......vendor
$ go help mod vendor
usage: go mod vendor [-e] [-v] [-o outdir]vendor est une alternative à gopath avant le lancement de gomod, chaque projet go aura un répertoire vendor, stockant les dépendances de chaque projet séparément selon le format domain/user/project, tout comme le node_module volumineux de nodeJs, les dépendances de chaque projet sont stockées séparément, cette méthode de gestion des dépendances semble vraiment stupide maintenant, mais à cette époque il n'y avait vraiment pas de meilleure solution, la raison pour laquelle vendor est conservé est parce que go adhère à l'engagement de rétrocompatibilité, certains anciens projets y compris le code source de go peuvent encore utiliser vendor.
Pour en revenir au sujet, vendor est une sous-commande de go mod, elle peut exporter les dépendances globales référencées par le module actuel vers le répertoire vendor.
$ go mod vendor -h
usage: go mod vendor [-e] [-v] [-o outdir]
Run 'go help mod vendor' for details.Elle dispose des paramètres suivants
-o: Spécifie le chemin du répertoire de sortie-v: Affiche chaque dépendance-e: Ne quitte pas en cas d'erreur et continue
Voici un exemple, utilisez d'abord go list -m all pour voir les dépendances référencées par le projet actuel
$ go list -m all
github.com/dstgo/task
github.com/davecgh/go-spew v1.1.1
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.0
github.com/stretchr/objx v0.5.0
github.com/stretchr/testify v1.8.4
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
gopkg.in/yaml.v3 v3.0.1Exportez vers le répertoire vendor actuel
$ go mod vendor -v -e -o vendor
# github.com/davecgh/go-spew v1.1.1
## explicit
github.com/davecgh/go-spew/spew
# github.com/pkg/errors v0.9.1
## explicit
github.com/pkg/errors
# github.com/pmezard/go-difflib v1.0.0
## explicit
github.com/pmezard/go-difflib/difflib
# github.com/stretchr/testify v1.8.4
## explicit; go 1.20
github.com/stretchr/testify/assert
# gopkg.in/yaml.v3 v3.0.1
## explicit
gopkg.in/yaml.v3La structure du répertoire après exportation est la suivante
└─vendor
├─github.com
│ ├─davecgh
│ │ └─go-spew
│ │ └─spew
│ ├─pkg
│ │ └─errors
│ ├─pmezard
│ │ └─go-difflib
│ │ └─difflib
│ └─stretchr
│ └─testify
│ └─assert
└─gopkg.in
| └─yaml.v3
|
|--modules.txtLe fichier modules.txt est un fichier qui décrit tous les éléments de dépendance, similaire au go.mod actuel.
verify
$ go help mod verify
usage: go mod verifyCette commande vérifiera si les dépendances du projet ont été modifiées après avoir été téléchargées localement. Par exemple, s'il n'y a pas de problème, elle affichera all modules verified
$ go mod verify
all modules verifiedSinon, elle signalera où des changements se sont produits, et terminera la commande avec un état anormal. Par exemple
$ go mod verify
gorm.io/gorm v1.25.5: dir has been modified (/go/mod/libs/gorm.io/gorm@v1.25.5)why
$ go help mod why
usage: go mod why [-m] [-vendor] packages...Explique pourquoi ce package est dépendant, affiche en fait le graphique des dépendances à son sujet. Par exemple
$ go mod why gorm.io/gorm
# gorm.io/gorm
golearn
gorm.io/gormPar défaut, analysera uniquement les importations depuis main, ajoutez le paramètre -m pour analyser la situation d'importation de chaque package.
work
La commande work est un outil de développement local pour la gestion multi-modules go
$ go work help
Work provides access to operations on workspaces.
Note that support for workspaces is built into many other commands, not
just 'go work'.
The commands are:
edit edit go.work from tools or scripts
init initialize workspace file
sync sync workspace build list to modules
use add modules to workspace file
vendor make vendored copy of dependencies
Use "go help work <command>" for more information about a command.init
La sous-commande init est utilisée pour initialiser un workspace, cette commande créera un fichier nommé go.work
$ go work init -h
usage: go work init [moddirs]
Run 'go help work init' for details.Accepte le paramètre [moddirs] pour spécifier quels modules inclure dans la gestion, par exemple
$ go work init ./service ./apiuse
La sous-commande use est utilisée pour ajouter des répertoires de modules gérés à go.work
$ go help work use
usage: go work use [-r] [moddirs]
Use provides a command-line interface for adding
directories, optionally recursively, to a go.work file.Accepte [moddirs] comme paramètre, et un -r pour rechercher récursivement des modules dans le chemin [moddirs], par exemple
$ go work use -r ./oss-api ./multi_modulesedit
Le rôle de la sous-commande edit est le même que go mod edit, toutes deux sont laissées à l'interface de ligne de commande pour que d'autres outils et scripts les utilisent.
$ go help work edit
usage: go work edit [editing flags] [go.work]
Edit provides a command-line interface for editing go.work,
for use primarily by tools or scripts. It only reads go.work;
it does not look up information about the modules involved.
If no file is specified, Edit looks for a go.work file in the current
directory and its parent directoriesLes paramètres sont les suivants
-fmt, formate le fichiergo.work-use,-dropuse, ajoute et supprime des chemins de modules-replace=old[@v]=new[@v],-dropreplace=old[@v]=new[@v], utilisés pour ajouter et supprimer des modules à remplacer-go,-toolchain=name, spécifie la version go, et spécifie la chaîne d'outils à utiliser-print, affiche les modifications finales, ne les réécrit pas dans le fichier-json, affiche au formatjson, ne peut pas être utilisé avec-print, la structure de type correspondante est la suivantegotype GoWork struct { Go string Toolchain string Use []Use Replace []Replace } type Use struct { DiskPath string ModulePath string } type Replace struct { Old Module New Module } type Module struct { Path string Version string }
Voici quelques exemples d'utilisation, sortie formatée
$ go work edit -fmt -print
go 1.22.0
use (
./ab/cd
./auth
./user
)Sortie json
$ go work edit -fmt -json
{
"Go": "1.22.0",
"Use": [
{
"DiskPath": "./ab/cd"
},
{
"DiskPath": "./auth"
},
{
"DiskPath": "./user"
}
],
"Replace": null
}sync
La sous-commande sync est utilisée pour synchroniser la liste des modules dans go.work vers les différents modules du workspace.
$ go help work sync
usage: go work sync
Sync syncs the workspace's build list back to the
workspace's modulesCe processus se produit principalement après le développement local terminé, chaque module a terminé le travail de publication, à ce moment, utilisez sync, il mettra à jour les dépendances dans go.mod de tous les modules du workspace en fonction des relations de dépendance de chaque module, nous évitant ainsi de mettre à jour manuellement.
vendor
La commande vendor copiera toutes les bibliothèques de dépendances de modules dans le workspace vers le répertoire vendor.
$ go work help vendor
usage: go work vendor [-e] [-v] [-o outdir]Fonctionne de la même manière que go mod vendor, donc je ne vais pas trop m'étendre.
vet
La commande vet est un outil de vérification statique des erreurs du code source go, tout comme les outils lint d'autres langages, comme Eslint.
$ go vet -h
usage: go vet [build flags] [-vettool prog] [vet flags] [packages]
Run 'go help vet' for details.
Run 'go tool vet help' for a full list of flags and analyzers.
Run 'go tool vet -help' for an overview.Prenons d'abord un exemple simple, voici le code source suivant
$ cat main.go
package main
import "fmt"
func main(){
fmt.Println("hello world!"
}Exécutez go vet sans aucun paramètre dans le même répertoire
$ go vet
vet: ./main.go:6:28: missing ',' before newline in argument list (and 1 more errors)vet signalera quel fichier, quelle ligne et quel problème. Elle prend en charge les drapeaux de construction comme paramètres, tels que -n et -x, prend en charge les packages, les répertoires, les noms de fichiers comme paramètres.
$ go vet .
$ go vet main.go
$ go vet ./cmd
$ go vet runtimeUtilisez la commande suivante pour afficher ses paramètres et explications plus détaillés.
$ go tool vet help
vet is a tool for static analysis of Go programs.
vet examines Go source code and reports suspicious constructs,
such as Printf calls whose arguments do not align with the format
string. It uses heuristics that do not guarantee all reports are
genuine problems, but it can find errors not caught by the compilers.
Registered analyzers:
asmdecl report mismatches between assembly files and Go declarations
assign check for useless assignments
atomic check for common mistakes using the sync/atomic package
bools check for common mistakes involving boolean operators
buildtag check //go:build and // +build directives
......La commande go tool vet ne peut pas être utilisée directement pour vérifier le code, vous devez utiliser go vet. Le paramètre [vet flag] de go vet prend en charge la définition des analyseurs de code, les valeurs disponibles sont les suivantes
asmdecl Vérifie si les fichiers assembleur correspondent aux déclarations go
assign Vérifie s'il y a des affectations inutiles
atomic Vérifie si l'atomicité est violée lors de l'utilisation de sync/atomic
bools Vérifie une utilisation incorrecte des opérateurs logiques
buildtag Vérifie les build tags
cgocall Vérifie les violations des règles de passage de pointeurs cgo
composites Vérifie les structures composites non initialisées, comme map, chan
copylocks Vérifie s'il y a une copie de valeur de verrou
directive Vérifie les instructions de la chaîne d'outils go
errorsas Vérifie si des types non pointeurs ou non error sont passés à errors.As
framepointer Vérifie si le code assembleur optimisé par compilation efface le pointeur de trame avant de le sauvegarder
httpresponse Vérifie une utilisation incorrecte de httpresponse
ifaceassert Vérifie les assertions de type d'interface à interface
loopclosure Problèmes de référence des variables de boucle
lostcancel context.WithCancel n'utilise pas la fonction cancel
nilfunc Vérifie s'il y a des comparaisons inutiles entre fonction et nil
printf Vérifie si les paramètres de formatage printf sont corrects
shift Vérifie s'il y a des décalages égaux ou supérieurs à la largeur des entiers
sigchanyzer Vérifie les chan os.Signal non tamponnés
slog Vérifie les appels de journalisation structurée illégaux
stdmethods Vérifie si les signatures des méthodes d'interface connues sont correctes
stringintconv Vérifie la conversion de chaînes en entiers
structtag Vérifie si les tags de structure sont corrects
testinggoroutine Vérifie si les协程 utilisent testing.Fatal dans les tests
tests Vérifie les utilisations courantes erronées des tests et exemples
timeformat Vérifie si le format de temps utilisé avec (time.Time).Format ou time.Parse est correct
unmarshal Passe des types non pointeurs ou non interface à unmarshal
unreachable Vérifie le code inaccessible
unsafeptr Vérifie les conversions incorrectes de uintptr en unsafe.Pointer
unusedresult Vérifie les valeurs de retour de fonction non utiliséesCe sont tous des analyseurs qui analysent un point spécifique, par exemple l'analyseur timeformat vérifie si le format d'appel de time.Format est conforme à la syntaxe correcte. Par défaut, tous les analyseurs ci-dessus sont activés, pour en activer un seul, utilisez le format suivant
$ go vet -timeformat main.goDésactiver un seul
$ go vet -timeformat=false main.goLe code source de ces analyseurs est situé dans cmd/vendor/golang.org/x/tools/go/analysis/passes, chaque analyseur est un piège facile dans le langage go, il est donc fortement recommandé d'utiliser la commande vet pour vérifier votre code. En plus de cela, elle prend également en charge d'autres paramètres de drapeau
-V, affiche uniquement la version puis quitte-json, affiche au format json-c=n, affiche le nombre spécifié de lignes de conflit dans le contexte (ne semble avoir aucun effet)
Il y a aussi des analyseurs externes, comme shadows, qui est responsable de la détection des problèmes de masquage de variables avec des noms de variables courts, comme il est externe, il doit être téléchargé avec go install
$ go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latestUtilisez le format suivant
$ go vet -vettool=$(which shadow)test
$ go test -h
usage: go test [build/test flags] [packages] [build/test flags & test binary flags]
Run 'go help test' and 'go help testflag' for details.La commande test est la commande qui fournit la fonctionnalité de test dans la chaîne d'outils du langage go, cette fonctionnalité est très importante, pour un logiciel, des tests complets sont indispensables. Ici, je vais simplement présenter brièvement comment utiliser la commande test, si vous souhaitez en savoir plus sur les tests, rendez-vous sur : Tests
En plus de prendre en charge les paramètres de compilation de la commande build, test prend également en charge les paramètres suivants
-args, paramètres d'entrée du programme-c, compile le fichier binaire de test du package actuel dans le répertoire actuel mais ne l'exécute pas, nommépkg.test-exec, exécute d'autres commandes avant le début du test-json, le style de sortie du test devient json-o, spécifie le chemin du fichier binaire de test
Elle prend également en charge de nombreux testflag, utilisez la commande help pour afficher tous les testflag
$ go help testflag
`go test` 命令既接受作用于 `go test` 本身的标志,
也接受作用于生成的测试二进制文件的标志。
`go test` 命令识别以下标志,并用于控制任何测试的执行:
-bench regexp
-benchtime t
-count n
......Présentation de quelques-uns couramment utilisés
-v, affiche les résultats de test de chaque cas.-timeout duration, temps d'exécution maximal du test-skip regexp, saute les cas de test spécifiés-short, réduit le temps d'exécution des cas de test qui prennent beaucoup de temps-shuffle, mélange l'ordre d'exécution de tous les cas de test-run regexp, exécute les cas de test spécifiés-list regexp, liste chaque cas de test-cpu 1,2,4, spécifie le nombre de cpu-count n, spécifie combien de fois chaque cas de test doit être exécuté
L'utilisation la plus simple est, sans aucun paramètre, elle exécutera tous les cas de test du package actuel et affichera les résultats.
$ ls *_test.go
hello_test.go
$ go test
PASS
ok golearn 0.522sSpécifier un fichier de test
$ go test hello_test.go
ok command-line-arguments 0.041sAjoutez le paramètre -v pour afficher une sortie plus détaillée, c'est très couramment utilisé.
$ go test -v hello_test.go
=== RUN TestHello
hello_test.go:6: hello world!
--- PASS: TestHello (0.00s)
PASS
ok command-line-arguments 0.041sSpécifier un cas de test
$ go test -v -run TestHello
=== RUN TestHello
hello_test.go:6: hello world!
--- PASS: TestHello (0.00s)
PASS
ok golearn 0.028sLors des tests, la commande test dispose de deux modes, parlons d'abord du mode répertoire, lorsque la commande test est exécutée sans le paramètre package, elle exécutera les tests en mode répertoire, par exemple les commandes suivantes
$ go test
$ go test -vDans ce mode, le cache de test est désactivé. L'autre mode est le mode liste, lorsque le paramètre package n'est pas vide, les tests seront exécutés en mode liste, la différence avec le premier est que le cache de test est activé ou non. Par exemple
$ go test -v .
$ go test -v ./...
$ go test .
$ go test -v net/httpEn mode liste, go compilera et exécutera les fichiers de test de chaque package sous le package spécifié en fichiers binaires, pour éviter d'exécuter les tests à plusieurs reprises, go mettra par défaut les résultats en cache, et ne recompilera pas lors de la deuxième exécution. Le cache sera activé par défaut lors de l'utilisation des paramètres suivants
-benchtime-cpu-list-parallel-runshort-timeout-failfast-v
Utiliser d'autres paramètres que ceux-ci permettra de désactiver le cache, la méthode recommandée par l'officiel est d'utiliser -count=1 pour désactiver le cache. Par exemple
$ go test -v -count=1 ./...Instructions
Contrairement aux commandes, les instructions go existent sous forme codée en dur dans les fichiers source, elles ont un autre nom plus technique : directives de compilation (pragma directives).
Les compilateurs et les éditeurs de liens modifieront leur propre comportement en raison d'elles afin d'atteindre le contrôle de la compilation, un peu comme les macros dans le langage C, bien sûr, toutes les instructions ne sont pas utilisées pour affecter la compilation, certaines sont utilisées pour d'autres comportements fonctionnels, par exemple l'instruction generate est généralement utilisée pour la fonctionnalité de génération de code. Ces instructions existent généralement sous forme de commentaires, et ont le préfixe //go:, sans aucun espace au milieu, par exemple l'instruction //go:generate. Tous les types d'instructions sont divisés en deux catégories
- Instructions fonctionnelles, ce sont des instructions fonctionnelles fournies par go qui peuvent être utilisées librement, comme
generate,embed,build. - Instructions du compilateur, ces instructions doivent être utilisées avec prudence, une utilisation abusive peut entraîner des résultats imprévisibles.
À l'exception des instructions fonctionnelles, la plupart des instructions ne peuvent agir que sur les signatures de fonctions. Pour les instructions du compilateur, vous pouvez exécuter la commande go doc compile pour afficher leurs instructions. Pour toutes les instructions, vous pouvez trouver des informations à leur sujet dans cmd/compile/internal/ir/node.go: 440.
generate
$ go help generate
usage: go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]L'instruction generate comme son nom l'indique est liée à la génération, généralement son rôle est d'exécuter des commandes qui génèrent du code et mettent à jour le code source, mais en réalité elle peut exécuter n'importe quelle commande. Et, l'instruction generate est différente des autres instructions, elle dispose d'une commande dédiée pour exécuter toutes les instructions generate situées dans les fichiers source. Elle peut utiliser des noms de fichiers ou des noms de packages comme paramètres d'entrée pour indiquer quels fichiers exécuter les instructions generate, voici ses autres paramètres.
-run=regex, exécute les instructions generate spécifiées-skip=regex, saute les instructions generate spécifiées-n, affiche les commandes qui seront exécutées-x, affiche les commandes exécutées pendant le processus-v, affiche les fichiers traités
En outre, les commandes exécutées dans l'instruction generate prennent également en charge les paramètres intégrés suivants
$GOARCH, architecture cpu$GOOS, système d'exploitation$GOFILE, nom de fichier$GOLINE, numéro de ligne$GOPACKAGE, nom du package$GOROOT, go root$DOLLAR, symbole dollar$PATH, variable d'environnement path
Prenons un exemple, pas de code, juste une ligne de commentaire
package main
//go:generate echo "hello world!"Exécutez la commande
$ go generate .
hello world!Cet exemple exécute une commande go
package main
//go:generate go versionExécutez la commande
$ go generate .
go version go1.21.3 windows/amd64L'instruction generate peut être utilisée pour exécuter n'importe quelle commande, comme swagger pour générer de la documentation API, ou Wire pour générer du code IOC. Cependant, cette instruction ne convient pas pour exécuter des commandes trop complexes, elle convient pour exécuter des commandes courtes, s'il y a des besoins complexes, vous pouvez utiliser des scripts ou makefile à la place.
embed
L'instruction embed est une nouvelle fonctionnalité ajoutée en 1.16, son rôle est d'emballer des fichiers statiques dans le fichier binaire, comme des modèles HTML, etc. Son format est le suivant
//go:embed patternpattern peut être une expression glob, un répertoire ou un fichier spécifique. Prenons un exemple
package main
import "embed"
//go:embed *
var static embed.FSL'instruction embed doit être située au-dessus d'une variable globale de type embed.Fs, notez qu'elle doit être une variable globale, et son utilisation nécessite d'importer le package embed, dans cet exemple, * représente que tous les fichiers du répertoire actuel seront emballés dans le fichier binaire, mais elle n'autorisera pas les répertoires commençant par ..
L'exemple suivant montre comment lire le contenu à partir de fichiers intégrés
package main
import (
"embed"
"fmt"
)
//go:embed *.txt
var static embed.FS
func main() {
bytes, err := static.ReadFile("hello.txt")
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}Il n'a que trois méthodes, l'utilisation n'est pas différente d'un système de fichiers normal, et comme il implémente l'interface io/Fs, il peut également être transmis en tant qu'objet Fs.
func (f FS) Open(name string) (fs.File, error)
func (f FS) ReadFile(name string) ([]byte, error)
func (f FS) ReadDir(name string) ([]fs.DirEntry, error)L'exemple suivant montre comment intégrer des fichiers html via l'instruction embed, et y accéder via un service http.
package main
import (
"embed"
"net/http"
)
//go:embed index.html
var htmlFs embed.FS
func main() {
http.Handle("/", http.FileServer(http.FS(htmlFs)))
http.ListenAndServe(":8080", http.DefaultServeMux)
}Le résultat d'accès est le suivant
$ curl -s -GET 127.0.0.1:8080
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello world!</title>
</head>
<body>
<H1>Hello World!</H1>
<script>
alert("hello world!");
</script>
</body>
</html>L'instruction embed prend également en charge le type de variable globale []byte, par exemple
package main
import (
_ "embed"
"net/http"
)
//go:embed index.html
var rawdata []byte
func main() {
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
writer.Write(rawdata)
})
http.ListenAndServe(":8080", http.DefaultServeMux)
}L'effet réalisé est similaire à l'exemple précédent.
$ curl -s -GET 127.0.0.1:8080
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello world!</title>
</head>
<body>
<H1>Hello World!</H1>
<script>
alert("hello world!");
</script>
</body>
</html>build
Dans la section build-Contrôle de compilation, nous avons parlé de l'utilisation de l'instruction // +build pour contrôler le comportement de compilation. L'instruction //go:build est une nouvelle fonctionnalité ajoutée en 1.17, destinée à remplacer l'instruction précédente, mais maintenant en 1.21 elle n'a pas encore été remplacée, elle existera probablement de manière coexistante à l'avenir, à propos de cette nouvelle instruction, la documentation officielle présente également une introduction : build constraints. Sa fonction n'est pas très différente de la précédente, mais la syntaxe est plus stricte, prend en charge les expressions booléennes, prenons un exemple
//go:build (linux && 386) || (darwin && !cgo)
package pkg_nameCette méthode est beaucoup plus lisible que l'ancienne.
line
L'instruction line affectera le numéro de ligne, le numéro de colonne et le nom de fichier de la ligne suivante, son rôle se limite à cela, la plupart du temps elle peut être utilisée pour déboguer des erreurs, etc. Par exemple, en cas d'erreur, elle modifiera les informations de sortie du compilateur.
package main
var a undefinedType
func main() {
}Normalement, le compilateur affichera
.\main.go:3:7: undefined: undefinedTypeMais si l'instruction line est utilisée, c'est différent
package main
//line abc.go:10:100
var a undefinedType
func main() {
}Alors la sortie sera
abc.go:10:106: undefined: undefinedTypeEt en raison de raisons historiques, l'instruction line est également la seule instruction dont l'utilisation est différente des autres instructions. Son format est
//line filename:line:columnVous pouvez voir qu'elle n'a pas besoin de go: comme préfixe.
linkname
Cette instruction peut être utilisée pour lier des fonctions ou des variables globales d'autres packages, même s'il s'agit de types privés, cette opération apparaît souvent dans la bibliothèque standard, en particulier dans runtime, certaines fonctions n'ont pas de corps de fonction et sont implémentées de cette manière, une autre partie des fonctions avec un corps de fonction vide est implémentée en assembleur. Voyons son utilisation, le format d'utilisation est le suivant
//go:linkname nom_lié type_liéEt avant utilisation, par exemple importez le package unsafe. Prenons un exemple simple de liaison d'un type privé dans la bibliothèque standard
import (
"fmt"
"unsafe"
)
//go:linkname memhash runtime.memhash
func memhash(p unsafe.Pointer, h, s uintptr) uintptr
func MemHash(data []byte) uint64 {
ptr := unsafe.Pointer(unsafe.SliceData(data))
return uint64(memhash(ptr, 0, uintptr(len(data))))
}
func main() {
fmt.Println(MemHash([]byte("hello")))
}Sortie
15395306441938000233Elle lie la fonction privée runtime.memhash à la fonction que nous avons déclarée, cette fonction n'a pas de corps de fonction, seulement une signature, sert uniquement de support. Le rôle de memhash est de calculer une somme de hachage en fonction de la mémoire, étant donné un pointeur, une graine de hachage et un décalage mémoire. Ce processus de liaison est effectué pendant la compilation,
Si ce n'est pas la bibliothèque standard, la situation est quelque peu différente, par exemple, il y a une fonction test dans le package example, avant la liaison, vous devez d'abord importer anonymement ce package.
package example
// Un type privé, inaccessible de l'extérieur.
func test() string {
return "a"
}package main
import (
"fmt"
_ "golearn/example"
_ "unsafe"
)
//go:linkname test golearn/example.test
func test() string
func main() {
fmt.Println(test())
}Sortie
aVous pouvez voir que la liaison a réussi, cette méthode peut contourner le système de modules go pour faire ce que vous voulez, mais il n'est pas recommandé de l'utiliser à grande échelle, à moins que vous ne sachiez ce que vous faites.
noinline
L'instruction noinline indique qu'une fonction est interdite d'optimisation d'inlining, même si elle est très simple. Prenons un exemple simple
package main
func val() string {
return "val"
}
func main() {
var c = val()
_ = c
}val est une fonction très simple, son rôle est de retourner un littéral de chaîne, comme elle est trop simple et que le résultat est toujours prévisible, alors lors de la compilation elle sera optimisée par le compilateur sous la forme suivante
package main
func main() {
var c = "val"
_ = c
}Voyons à quoi ressemble son assembleur, vous pouvez voir qu'il n'y a pas d'appel à la fonction val.
TEXT main.val(SB), NOSPLIT|NOFRAME|ABIInternal, $0-0
FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
LEAQ go:string."val"(SB), AX
MOVL $3, BX
FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
RETEnsuite, ajoutez l'instruction noinline
package main
//go:noinline
func val() string {
return "val"
}
func main() {
var c = val()
_ = c
}Voyons maintenant sa forme assembleur
CMPQ SP, 16(R14)
PCDATA $0, $-2
JLS 17
PCDATA $0, $-1
PUSHQ BP
MOVQ SP, BP
FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
PCDATA $1, $0
CALL main.val(SB)
POPQ BP
RETCette fois, vous pouvez voir très clairement l'appel main.val, et c'est exactement la fonction de l'instruction noinline, empêcher l'inlining de fonction lors de l'optimisation du compilateur.
nosplit
L'instruction nosplit sert à sauter la détection de débordement de pile. Comme le modèle de planification concurrente de go est une planification préemptive, supposons qu'une fonction exécutera du code très bas niveau, d'autres coroutines qui appellent cette fonction ne sont pas adaptées pour être préemptées, vous pouvez utiliser cette instruction pour l'indiquer.
//go:nosplit
func nosplitFn()Après avoir utilisé cette instruction, il n'y aura plus de croissance de pile.
noescape
noescape, comme son nom l'indique facilement, est lié à l'échappement, son rôle est d'indiquer que la fonction actuelle n'effectuera pas de comportement d'échappement mémoire, après l'exécution toutes les ressources sont récupérées, et cette fonction ne doit avoir qu'une signature sans corps de fonction, dans ce cas, l'implémentation de la fonction est généralement réalisée en assembleur.
Par exemple, memhash utilisé précédemment utilisera cette instruction
//go:noescape
//go:linkname memhash runtime.memhash
func memhash(p unsafe.Pointer, h, s uintptr) uintptrDe cette façon, le compilateur n'effectuera pas d'analyse d'échappement, à condition que vous garantissiez qu'il n'y aura pas d'échappement, s'il y en a, alors on ne sait pas quelles seront les conséquences.
uintptrescapes
L'instruction uintptrescapes indique que les paramètres de type uintptr dans cette fonction sont convertis en valeurs de pointeur et s'échappent vers le tas, et doivent rester vivants. Cette instruction est généralement utilisée pour certains appels système de bas niveau, dans la plupart des cas, il n'est pas nécessaire de la comprendre.
//go:uintptrescapes
func nosplit(ptr uintptr) uintptrAuparavant, il devrait y avoir eu une instruction notinheaps utilisée pour indiquer qu'un type n'est pas autorisé à allouer de la mémoire sur le tas, je ne sais pas dans quelle version elle a été supprimée.
norace
L'instruction norace indique que l'accès mémoire d'une fonction n'a plus besoin d'analyse de course, généralement utilisé lors de l'exécution de code de bas niveau qui ne convient pas à l'analyse de course.
//go:norace
func low_level_code(ptr uintptr) uintptrTIP
Certaines instructions sont limitées à une utilisation par le package runtime uniquement, externes ne peuvent pas les utiliser, elles impliqueront des choses plus profondes, si vous souhaitez en savoir plus, vous pouvez voir leur introduction dans Runtime-only compiler directives.
