Kommandozeile

Befehle in Go enthalten eine vollständige Toolchain. Diese Befehle umfassen Dokumentation, Formatierung, Code-Überprüfung, Kompilierung, Tests, Abhängigkeitsmanagement und vieles mehr. Sie decken praktisch alle Aspekte der Go-Entwicklung ab.
bug Fehler melden
build Pakete und Abhängigkeiten kompilieren
clean Objektdateien entfernen
doc Dokumentation im Quellcode anzeigen
env Go-Umgebungsvariablen anzeigen
fix API-Kompatibilitätsprobleme aufgrund von Go-Versionsänderungen beheben
fmt Quellcode formatieren
generate Code-Generierung
get Abhängigkeiten hinzufügen
install Pakete installieren und kompilieren
list Paket/Modul auflisten
mod Modul-Wartungsbefehle
work Workspace-Wartungsbefehle
run Kompilieren und ausführen
test Testen
tool Angegebenes Go-Tool ausführen
version Go-Versionsinformationen anzeigen
vet Mögliche Probleme im Quellcode scannen und meldenDieser Artikel beschreibt lediglich deren Verwendung. Alle Inhalte stammen aus der offiziellen Dokumentation. Für weitere Details besuchen Sie bitte cmd/go.
help
Der erste Befehl, den Sie kennenlernen sollten, ist help. Damit können Sie die Verwendung von Befehlen nachlesen. Es gibt zwei Verwendungsmöglichkeiten: Wenn Sie kurze Verwendungsinformationen erhalten möchten, fügen Sie dem Befehl das -h-Flag hinzu, zum Beispiel:
$ go env -h
usage: go env [-json] [-u] [-w] [var ...]
Run 'go help env' for details.Go zeigt kurz die Verwendung des Befehls an. Es wird auch darauf hingewiesen, dass Sie den help-Befehl verwenden sollten, um detailliertere Informationen zu erhalten:
$ 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'.Nutzen Sie den help-Befehl, um mehr über die Verwendung von Befehlen zu erfahren.
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 exportedDer doc-Befehl gibt Dokumentationskommentare für angegebene Pakete, Konstanten, Funktionen, Typen, Variablen, Methoden und sogar Strukturfelder aus. Ohne Argumente gibt er die Kommentare des aktuellen Pakets aus:
$ go docSie können auch ein bestimmtes Paket angeben, zum Beispiel die Dokumentation des runtime-Pakets:
$ 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.
......Oder einen bestimmten Typ:
$ 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.
...Oder eine bestimmte Funktion:
$ 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.Es gibt folgende häufig verwendete Flags:
-u: Private Typen anzeigen-all: Alle Dokumentationen eines Pakets anzeigen-short: Nur eine kurze Beschreibung pro Symbol-src: Quellcode ausgeben-cmd: Für Pakete, die zu Go-Befehlen gehören, auch die Code-Dokumentation innerhalb des Pakets ausgeben.
Zum Beispiel die Variable runtime.inf, die nicht exportiert ist:
$ go doc -u runtime.inf
package runtime // import "runtime"
var inf = float64frombits(0x7FF0000000000000)Der doc-Befehl hilft Ihnen, Dokumente bequemer zu lesen.
Eine weitere Möglichkeit, die Dokumentation von Befehlen zu lesen, besteht darin, den Quellcode zu lesen. Da einige Befehle nicht so detailliert dokumentiert sind, findet man im Quellcode oft ausführlichere Erklärungen. Da diese Befehle alle in Go geschrieben sind, ist das Lesen sehr bequem. Diese Befehle befinden sich im src/cmd-Paket, wobei jedes Unterpaket einen separaten Befehl darstellt. Der Einstiegspunkt befindet sich in der Datei 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,
}
}Hier finden Sie alle Go-Unterbefehle und deren Hilfsdokumentationen.
bug
$ go help bug
usage: go bug
Bug opens the default browser and starts a new bug report.
The report includes useful system information.Dieser Befehl hat keine Parameter oder Flags. Er öffnet Ihren Standardbrowser und ruft die Issue-Seite des github.com/golang/go-Repositories auf, um Ihnen das Melden von Fehlern zu erleichtern. Darüber hinaus hat er keine weitere Funktion.
version
Mit dem version-Befehl können Sie die aktuelle Go-Versionsinformation anzeigen.
$ go version -h
usage: go version [-m] [-v] [file ...]Ohne Parameter gibt er die aktuelle Go-Sprachversion aus:
$ go version
go version go1.21.0 windows/amd64Er akzeptiert auch Dateipfade als Parameter und gibt die Go-Version aus, die beim Kompilieren aller erkennbaren Binärdateien in diesem Pfad verwendet wurde.
$ 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.0Das -v-Flag weist den version-Befehl an, die Go-Version von nicht erkennbaren Dateien auszugeben. Das -m-Flag gibt Modulinformationen und einige Kompilierungsparameter der Binärdatei aus. Hier ein einfaches Beispiel:
$ 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 selbst ist eine Binärdatei. Tatsächlich gibt go version ohne Parameter die Go-Sprachversion seiner eigenen Binärdatei aus, da alle Toolchains von cmd/go von der Go-Sprache selbst implementiert werden.
env
Mit dem env-Befehl können Sie alle Go-Umgebungsvariablen anzeigen. Das Ändern dieser Umgebungsvariablen beeinflusst das Verhalten der Go-Toolchain.
$ go env -h
usage: go env [-json] [-u] [-w] [var ...]
Run 'go help env' for details.Ohne Parameter gibt der Befehl die Werte aller Go-Umgebungsvariablen aus:
$ go env
set GO111MODULE=on
set GOARCH=amd64
...Wenn Sie den Namen einer Umgebungsvariable als Parameter angeben, wird nur der Wert dieser Variable ausgegeben:
$ go env GO111MODULE
onMit -json wird die JSON-Form ausgegeben:
$ go env -json
{
"AR": "ar",
"CC": "gcc",
......
}Mit dem -w-Flag und dem Parameter im Format var=value wird der Wert einer Variable dauerhaft geändert:
$ go env -w GO111MODULE=onMit dem -u-Flag können Sie eine Variable auf den Standardwert zurücksetzen:
$ go env -u GO111MODULEMit go help environment können Sie die Beschreibung jeder Umgebungsvariable anzeigen:
$ 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.
......Im Folgenden werden einige häufig verwendete Umgebungsvariablen vorgestellt:
GOVERSION
Der Wert dieser Umgebungsvariable hängt von der Go-Sprachversion ab, die in der Datei $GOROOT/VERSION gespeichert ist. Diese Datei enthält die aktuelle Go-Version und Build-Zeit.
$ cat $GOROOT/VERSION
go1.21.3
time 2023-10-09T17:04:35ZDer Wert der runtime.Version-Variable ist identisch mit GOVERSION, und diese Umgebungsvariable kann nicht geändert werden.
GOENV
Im $GOROOT-Verzeichnis befindet sich eine Standard-Konfigurationsdatei namens go.env:
$ 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=autoDas Format ist einfach key=value. Die mit go env -w key=value geänderten Umgebungsvariablen werden in die Konfigurationsdatei geschrieben. Sie können jedoch auch eine benutzerdefinierte Konfigurationsdatei verwenden. Die GOENV-Umgebungsvariable kann den Pfad der env-Konfigurationsdatei manuell festlegen. Der Wert der GOENV-Umgebungsvariable kann nur durch Betriebssystem-Umgebungsvariablen überschrieben werden, nicht durch den go env -w-Befehl.
GOHOSTARCH
Repräsentiert die CPU-Architektur des lokalen Rechners. Dient nur zur Anzeige. Der Wert dieser Umgebungsvariable wird nicht aus der Konfigurationsdatei gelesen und kann nicht geändert werden.
GOHOSTOS
Repräsentiert das Betriebssystem des lokalen Rechners. Dient nur zur Anzeige. Der Wert dieser Umgebungsvariable wird nicht aus der Konfigurationsdatei gelesen und kann nicht geändert werden.
GOOS
Beim Kompilieren bestimmt der Wert von GOOS, für welches Zielsystem die Binärdatei kompiliert wird. Der Standardwert ist GOHOSTOS, also das lokale Betriebssystem. Es gibt folgende Optionen:
linuxdarwinwindowsnetbsdaixandroid
Tatsächlich werden mehr Betriebssysteme unterstützt. Verwenden Sie den Befehl go tool dist list, um alle unterstützten Werte anzuzeigen:
$ 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
Beim Kompilieren bestimmt der Wert von GOARCH, welche CPU-Architektur-Anweisungen beim Kompilieren verwendet werden. Der Standardwert ist GOHOSTARCH, also die lokale CPU-Architektur. Es gibt folgende Optionen:
amd64386armppc64
Tatsächlich werden mehr Architekturen unterstützt. Verwenden Sie den Befehl go tool dist list, um alle unterstützten Werte anzuzeigen:
$ go tool dist list | awk -F '/' '{print $2}' | awk '!seen[$0]++'
ppc64
386
amd64
arm
arm64
riscv64
wasm
loong64
mips
mips64
mips64le
mipsle
ppc64le
s390xBeachten Sie, dass GOOS und GOARCH nicht beliebig kombiniert werden können. Einige Betriebssysteme unterstützen nur bestimmte CPU-Architekturen.
GOROOT
GOROOT repräsentiert das Stammverzeichnis der Go-Installation. Der Wert von GOROOT kann nicht direkt geändert werden und kann nur durch Betriebssystem-Umgebungsvariablen überschrieben werden.
$ ls $GOROOT -1
api
bin
codereview.cfg
CONTRIBUTING.md
doc
go.env
lib
LICENSE
misc
PATENTS
pkg
README.md
SECURITY.md
src
test
VERSIONIm Stammverzeichnis befinden sich mehrere wichtige Ordner oder Dateien:
lib: Enthält einige Abhängigkeiten. Derzeit nur eine Bibliothek mit Zeitzoneninformationen verschiedener Länder, gespeichert in$GOROOT/lib/time. Kompilierte Binärdateien enthalten diese Zeitzoneninformationen nicht.pkg: Enthält einige Tool-Bibliotheken und Header-Dateien. Zum Beispiel sucht der Befehlgo toolim Verzeichnis$GOROOT/pkg/toolnach den Binärdateien der Go-Toolchain.bin: Enthält Binärdateien. Standardmäßig nur die ausführbaren Dateiengoundgofmt.$GOROOT/binsollte zum System-Pfad hinzugefügt werden, andernfalls können Go-Befehle nicht verwendet werden.src: Enthält Go-QuellcodeVERSION: Diese Datei enthält Versionsinformationen der Go-Sprache.go.env: Dies ist die Standard-env-Konfigurationsdatei.
GOPATH
Der Standardwert von GOPATH ist $HOME/go. Der Wert dieser Umgebungsvariable gibt an, wo importierte Dateien bei der Auflösung von import-Anweisungen gesucht werden. In der frühen Zeit vor gomod wurde GOPATH speziell zum Speichern verschiedener Drittanbieter-Bibliotheken verwendet. Die Struktur ist wie folgt:
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)Nach der Einführung von gomod dient GOPATH nur noch zum Speichern von mit go get heruntergeladenen Abhängigkeiten sowie zum Speichern von mit go install heruntergeladenen und kompilierten Binärdateien. Beachten Sie, dass der Speicherort von GOPATH nicht mit GOROOT identisch sein darf, andernfalls hat er keine Wirkung.
$ go env GOBIN
warning: GOPATH set to GOROOT (/home/user/go) has no effectZum Zeitpunkt der Erstellung dieses Artikels ist die Go-Sprachversion bereits bei go1.21.3 angekommen. Abgesehen von sehr alten Projekten verwendet praktisch niemand mehr gopath zur Abhängigkeitsverwaltung.
GOBIN
GOBIN dient zum Speichern von Drittanbieter-Binärdateien, die mit go install heruntergeladen und kompiliert wurden. Der Standardwert ist $GOPATH/bin. Wie $GOROOT/bin sollte auch dieses Verzeichnis zum Betriebssystem-Pfad hinzugefügt werden, andernfalls können die Binärdateien im GOBIN-Verzeichnis nicht verwendet werden.
GOMODCACHE
GOMODCACHE gibt den Speicherort für mit go get heruntergeladene Abhängigkeiten an. Der Standardwert ist $GOPATH/pkg/mod. Das Speicherformat ist wie folgt:
$GOMODCACHE/domain/username/project@verionAuf derselben Ebene befindet sich ein Ordner namens sumdb, der Informationen zur Abhängigkeitsprüfsummen-Datenbank enthält.
GOCACHE
Speichert Cache-Informationen für die Kompilierung. Der Standardwert ist $HOME/.cache/go-build. In diesem Verzeichnis wird eine README-Datei generiert.
$ 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.Jeder build-Vorgang erzeugt viele Dateien. Go cached diese Dateien, um sie bei der nächsten Kompilierung wiederzuverwenden.
GOTEMPDIR
Dient zum Speichern temporärer Dateien, die während der Kompilierung entstehen, z. B. temporäre Binärdateien für go run. Der Standardwert ist das vom Betriebssystem angegebene temporäre Verzeichnis. Unter macOS oder Linux ist es /tmp, unter Windows %TEMP%. Es kann auch auf einen benutzerdefinierten Speicherort geändert werden.
GO111MODULE
Diese Umgebungsvariable bestimmt, welche Methode zur Verwaltung von Go-Projektabhängigkeiten verwendet wird. Es gibt drei verfügbare Werte:
off: Deaktiviert gomod, verwendet gopath und ignoriert allego.mod-Dateien.on: Verwendet gomod, nicht gopath (Standard).auto: Automatische Erkennung. Wenn die Projektdatei einego.mod-Datei enthält, wird gomod zur Verwaltung verwendet.
TIP
Warum heißt es GO111MODULE und nicht einfach GOMODULE? Weil gomod erstmals in Go-Version 1.11 eingeführt wurde.
GOPROXY
Go-Modul-Proxy. Der Standardwert ist https://proxy.golang.org,direct. URLs werden durch Kommas getrennt. direct bedeutet, dass der Modul-Proxy direkt übersprungen und VCS verwendet wird. Letzteres wird nur ausgeführt, wenn ersteres nicht zugänglich ist. Eine weitere verfügbare Option ist off, die das Herunterladen von Modulen verbietet. Darüber hinaus kann GOPROXY auch eine Dateiadresse sein, zum Beispiel:
GOPROXY=file://$(go env GOMODCACHE)/cache/downloadMit go get -x können Sie die während des Abhängigkeits-Download-Prozesses ausgeführten Befehle anzeigen und so feststellen, ob ein Proxy verwendet wird.
$ 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.1Die Verwendung eines Modul-Proxys kann die Download-Geschwindigkeit von Modulen effektiv verbessern. Benutzer in China können standardmäßig den offiziellen Proxy nicht ohne Proxy-Zugriff访问. Derzeit sind folgende öffentliche und vertrauenswürdige Drittanbieter-Modul-Proxys verfügbar:
https://proxy.golang.com.cn: Open Source und bietet Enterprise-Dienstehttps://goproxy.cn: Bereitgestellt und Open Source von Qiniu Cloud
Es gibt auch Open-Source-Lösungen für selbst gehostete Modul-Proxys: goproxy
GOSUMDB
GOSUMDB wird verwendet, um die Adresse der Prüfsummen-Datenbank für Abhängigkeitsbibliotheken festzulegen. Standardmäßig ist es sum.golang.org. Wenn Sie einen Proxy eingestellt haben,访问 Go über den Proxy auf die Prüfdatenbank zu.
GOPRIVATE
Die GOPRIVATE-Umgebungsvariable wird verwendet, um private Repositories festzulegen. Übereinstimmende Repositories werden nicht über sumdb überprüft und verwenden keinen Proxy, sondern laden Abhängigkeiten direkt über VCS herunter. Es unterstützt Wildcard-Einstellungen, getrennt durch Kommas. Wie unten gezeigt, werden alle Abhängigkeiten mit dem Suffix corp.example.com und名为github.com/gohper/myproject keinen Proxy und sumdb verwenden.
GOPRIVATE=*.corp.example.com,github.com/gohper/myprojectSie können auch einen bestimmten Benutzer oder eine Organisation festlegen:
GOPRIVATE=github.com/gopher,github.com/myorganizationGONOPROXY
Gibt an, welche Abhängigkeiten keinen Proxy verwenden sollten. Die Regeln sind mit GOPRIVATE identisch und überschreiben GOPRIVATE.
GONOSUMDB
Gibt an, welche Abhängigkeiten keine Prüfdatenbank verwenden sollten. Die Regeln sind mit GOPRIVATE identisch und überschreiben GOPRIVATE.
GOINSECURE
Gibt an, welche Abhängigkeiten direkt über VCS heruntergeladen werden sollen. Die Regeln sind mit GOPRIVATE identisch und werden von GONOPROXY und GONOSUMDB überschrieben.
GOVCS
Legt das Versionskontrollsystem für die Modulverwaltung fest. Standardmäßig public:git|hg,private:all. Sie können auch VCS für bestimmte Domains einschränken, zum Beispiel:
GOVCS=github.com:git,evil.com:off,*:git|hgIn den obigen Einschränkungen kann github nur git verwenden, evil.com ist nicht erlaubt. Verwenden Sie |, um mehrere VCS anzugeben. Wenn Sie keine Einschränkungen vornehmen möchten, können Sie Folgendes einstellen:
GOVCS=*:allWenn Sie die Verwendung von VCS nicht允许 möchten, können Sie Folgendes einstellen:
GOVCS=*:offGOWORK
Legt fest, ob der Workspace aktiviert ist. Standardmäßig leer, d. h. aktiviert. Wenn auf off gesetzt, wird deaktiviert und alle go.work-Dateien werden ignoriert.
GOTOOLDIR
Legt den Speicherort der zu verwendenden Go-Toolchain fest. Standardmäßig $GOROOT/pkg/tool, wo auch die Standard-Toolchain gespeichert ist.
GODEBUG
Legt Debug-Optionen fest, um das Ausführungsverhalten bestimmter Teile von Go-Programmen über Schlüssel-Wert-Paare zu steuern, zum Beispiel:
GODEBUG=http2client=0,http2server=0Diese Einstellungen dienen dazu, bei Inkompatibilitäten während Versionsaktualisierungen ein Zurücksetzen auf das alte Verhalten zu ermöglichen. Zum Beispiel允许 panic(nil) in Version 1.21 nicht mehr. Dafür hat das Go-Team offiziell GODEBUG History dokumentiert. Weitere Details finden Sie unter GODEBUG.
CGO_ENABLED
Gibt an, ob cgo aktiviert ist. Standardmäßig 1, d. h. aktiviert. Auf 0 setzen, um es zu deaktivieren.
Die oben genannten Umgebungsvariablen sind die häufig verwendeten. Für weniger häufig verwendete wie CGO, WASM usw. wird hier nicht weiter eingegangen. Bei Interesse können Sie sich selbst informieren.
build
Go unterstützt zwei Compiler: gccgo und gc. gcc ist ein alter C/C++-Compiler, der mehrere Sprachen einschließlich Go unterstützt. Letzterer, gc, steht nicht für Garbage Collection, sondern für Go Compiler. Go wurde in Version 1.5 selbst kompiliert. gc ist ein vollständig in Go geschriebener Compiler, dessen Quellcode sich im cmd/compile-Paket befindet. Da er vollständig in Go implementiert ist, ist es sehr bequem, die internen Mechanismen zu verstehen und zu lernen. Standardmäßig verwendet der Compiler gc. Übrigens gibt es auch zwei Go-Debugger: gdb und dlv. Ersterer ist ein alter C/C++-Debugger, der mehrere Sprachen einschließlich Go unterstützt. Letzterer ist ein in Go geschriebener Debugger, der Go besser unterstützt. Er ist ebenfalls Open Source und wird empfohlen.
Der build-Befehl kompiliert Go-Quelldateien zu ausführbaren Binärdateien. Sie werden ein sehr schnelles Kompilierungserlebnis erleben, was eine der Eigenschaften von Go ist.
$ go build -h
usage: go build [-o output] [build flags] [packages]
Run 'go help build' for details.Er akzeptiert drei Parameter: den mit -o angegebenen Dateiausgabepfad, Build-Flags zur Steuerung des Kompilierungsverhaltens und zuletzt das zu kompilierende Paket. Dieser Parameter muss am Ende stehen. Hier ein einfaches Beispiel ohne Build-Flags:
# Windows
$ go build -o .\bin\golearn.exe golearn
# macOS / Linux
$ go build -o ./bin/golearn golearn./bin/golearn.exe ist der Ausgabepfad, golearn ist das zu kompilierende Modul. Es kann auch eine Hauptdatei oder ein Ordner sein. Zum Beispiel wird im folgenden einfachen Beispiel main.go als Kompilierungsziel verwendet:
# Windows
$ go build -o .\bin\golearn.exe main.go
# macOS / Linux
$ go build -o ./bin/golearn main.goBeim Kompilieren werden alle Dateien, die auf _test.go enden, ignoriert, da es sich vereinbarungsgemäß um Testdateien handelt.
Darüber hinaus unterstützt der build-Befehl zahlreiche Build-Flags zur Steuerung des Kompilierungsverhaltens.
-x: Detaillierte Anweisungen während des Kompilierungsprozesses ausgeben-n: Ähnlich wie-x, gibt aber nur die Anweisungen aus, ohne sie tatsächlich auszuführen.-v: Kompilierte Pakete ausgeben-p: Parallelität während des Kompilierungsprozesses-a: Erzwingt erneutes Kompilieren, auch wenn bereits aktuell.-compiler: Welcher Compiler verwendet werden soll,gccgoodergc. Letzterer ist der in Go geschriebene Compiler.-race: Race-Detection aktivieren-msan: Speicheranalyse aktivieren-asan: Adressanalyse aktivieren-cover: Code-Coverage-Detection aktivieren-buildmode: Kompilierungsmodus angeben. Optionen:archive,c-archive,c-shared,default,shared,exe,pie,plugin.-pgo: PGO-Datei angeben-trimpath: Quellcode-Pfadpräfixe entfernen. Zum Beispiel wird aus dem relativen Pfad/var/lib/go/src/main.gonach dem Entfernen nur der relative Pfad/main.gozur Modul-Pfad. Nach Aktivierung dieser Option steigt die Kompilierungszeit deutlich, etwa 20-40%, abhängig von der Anzahl der Dateien.-toolexec: Vor der Kompilierung auszuführende Go-Befehle. Format:-toolexec 'cmd args'.-gcflags: Bestimmte Tags für den gc-Compiler angeben-gccgoflags: Bestimmte Tags für den gccgo-Compiler angeben-ldflags: Bestimmte Tags für das Link-Tool angeben
Für Parameter wie ldflags können Sie -help übergeben, um mögliche Werte anzuzeigen, zum Beispiel:
$ 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
......Die oben genannten sind die häufig verwendeten. Für andere weniger häufig verwendete können Sie sich selbst informieren.
gcflags
Mit gcflags können Sie Parameter an den gc-Compiler übergeben, um bestimmtes Verhalten zu steuern. Das Format ist -gcflags="pattern=args list", wobei args list die Parameterliste ist und pattern den Wirkungsbereich angibt. Es gibt folgende verfügbare Werte:
main: Top-Level-Paketpfad der Hauptdateiall: Aktuelles Modul und alle Abhängigkeiten im aktuellen Modusstd: Standardbibliothekcmd: Alle Quelldateien imcmd-Paket- Wildcards, z. B.
.,./...,cmd/....
Diese pattern-Regel gilt für alle Flags, die dieses Format unterstützen, z. B. ldflags. Mit folgendem Befehl können Sie verfügbare Parameter anzeigen:
$ go build -gcflags -help
usage: compile [options] file.go...
-% debug non-static initializers
-+ compile runtime
-B disable bounds checking
-C disable printing of column numbers in error messages
-D path
set relative path for local imports
-E debug symbol export
-I directory
add directory to import search path
-K debug missing line numbers
-L show actual source file name for error locations affected by //line directives
-N disable optimizations
-S print assembly listing
-V print version and exit
-W debug parse tree after type checking
......Im Folgenden werden einige häufig verwendete Parameter vorgestellt:
-S: Gibt die Assembly-Form des Codes aus-N: Deaktiviert Kompilierungsoptimierungen-m: Gibt Optimierungsentscheidungen aus-l: Deaktiviert Funktions-Inlining-c: Parallelität der Kompilierung-dwarf: DWARF-Symbole generieren
Wenn Sie beispielsweise die Assembly-Form des Codes anzeigen möchten, können Sie den -S-Parameter verwenden und Optimierungen und Inlining deaktivieren, um die ursprüngliche Form wiederherzustellen:
$ 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
Mit ldflags können Sie Parameter an den Linker übergeben, um bestimmtes Verhalten zu steuern. Mit folgendem Befehl können Sie alle verfügbaren Werte für ldflags anzeigen, fast 20-30 Stück:
$ 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)
.....Der -X-Parameter von ldflags ist eine sehr praktische Funktion. Er ermöglicht das Definieren von String-Variablenwerten指定 Pakets während des Linkens. Mit dieser Funktion können wir bequem Metainformationen zur Kompilierungszeit injizieren. Da es sich nur um eine Variable handelt, ist sie auch zur Laufzeit leicht abrufbar. Hier ein einfaches Beispiel:
package main
import "fmt"
var (
Version string
)
func main() {
fmt.Println(Version)
}Befehl ausführen:
go build -ldflags "-X main.Version=$(git describe --always)" main.goNach dem Ausführen wird die SHA1-Prüfsumme des Git-Commits ausgegeben:
5e3fd7aWeitere praktische Parameter sind:
-w: Generiert kein DWARF, was Informationen zur Quellcode-Debugging erleichtert.-s: Deaktiviert die Symboltabelle
Diese beiden werden normalerweise zusammen verwendet und können die Größe der kompilierten Binärdatei erheblich reduzieren, etwa 40%-50%. Der Nachteil ist jedoch offensichtlich: Debugging ist nicht möglich. Hier ein Beispiel:
$ go build -ldflags="-w -s" main.goCross-Kompilierung
Die Go-Kompilierung hat zwei Hauptmerkmale: Erstens schnell, zweitens Cross-Kompilierung. Cross-Kompilierung bedeutet, dass Sie lokal Zielcode für andere Systeme kompilieren können, z. B. auf windows Binärdateien für linux oder darwin kompilieren und umgekehrt. Viele Sprachen unterstützen Cross-Kompilierung, was nichts Besonderes ist. Aber Go macht Cross-Kompilierung sehr einfach, nur in zwei Schritten:
- Umgebungsvariable GOOS setzen, um das Zielbetriebssystem auszuwählen
- Umgebungsvariable GOARCH setzen, um die Ziel-CPU-Architektur auszuwählen
- Wie gewohnt
go buildzur Kompilierung verwenden
Der gesamte Prozess ist sehr kurz, erfordert keine zusätzlichen Tools oder Konfigurationen, und die Geschwindigkeit ist wie gewohnt schnell. Wie unten gezeigt:
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_winDer erste Schritt SET CGO_ENABLED=0 deaktiviert cgo. Sobald Ihr Code cgo verwendet, kann Cross-Kompilierung nicht normal verwendet werden. Der zweite Schritt SET GOOS legt das Zielsystem fest. Optionen sind linux, darwin, windows, netbsd. Der dritte Schritt legt die CPU-Architektur fest, SET GOARCH. Optionen sind amd64, 386, arm, ppc64. Der letzte Schritt ist die Kompilierung wie gewohnt.
Kompilierungssteuerung
Der build-Befehl kann mit tags das Kompilierungsverhalten steuern. Es handelt sich um eine Art Anweisung im Quellcode. Sehen Sie sich ein Beispiel an, die Datei product.go:
// +build product
package main
import "fmt"
func main() {
fmt.Println("product")
}Die Datei debug.go:
// +build debug
package main
import "fmt"
func main() {
fmt.Println("debug")
}Beide haben eine // +build-Anweisung, die angibt, unter welchen Bedingungen sie kompiliert werden. Das Grundformat lautet:
// +build tag1 tag2
package pkg_nameEs gibt mehrere zu befolgende Regeln:
- Zwischen
//und+buildmuss ein Leerzeichen sein. - Sie muss über der Paketdeklaration stehen.
- Es muss eine leere Zeile zwischen ihr und der Paketdeklaration sein.
Darüber hinaus kann sie durch einfache Abstände logisch gesteuert werden: Leerzeichen bedeutet OR, Komma bedeutet AND, ! bedeutet NOT. Zum Beispiel:
// +build windows linux
package pkg_nameBedeutet, dass die aktuelle Datei unter Windows oder Linux kompiliert wird.
// +build windows,amd64,!cgo linux,i386,cgo
package pkg_nameDieses Beispiel bedeutet, dass sie nur kompiliert wird, wenn es sich um die Windows-Plattform mit amd64-Architektur und cgo nicht aktiviert ist, ODER die Linux-Plattform mit i386-Architektur und cgo aktiviert ist. Wenn Sie einfach nur möchten, dass eine Datei nicht kompiliert wird, können Sie ignore verwenden:
// +build ignore
package pkg_nameEs können auch mehrere Zeilen von Anweisungen existieren:
// +build windows
// +build amd64
package pkg_nameMehrzeilige Anweisungen werden mit AND verarbeitet. Für Plattformen und Architekturen werden diese Tags beim Kompilieren automatisch von Go übergeben. Wir können auch benutzerdefinierte Tags übergeben. Nehmen wir die beiden Dateien vom Anfang als Beispiel:
$ go build -tags="debug" . && ./golearn.exe
debug
$ go build -tags="product" . && ./golearn.exe
productWie Sie sehen können, ergibt die Ausgabe bei verschiedenen Tags unterschiedliche Ergebnisse. Damit ist das Ziel der Kompilierungssteuerung erreicht.
run
Sowohl der run-Befehl als auch build kompilieren den Quellcode. Der Unterschied besteht darin, dass der run-Befehl nach der Kompilierung direkt ausführt. Um die Kompilierungsgeschwindigkeit zu beschleunigen, generiert der run-Befehl während des Kompilierungsprozesses keine Debug-Informationen, unterstützt also kein Debugging. Außerdem wird nur eine temporäre Binärdatei generiert, die normalerweise im GOTMEPDIR-Verzeichnis gespeichert wird, z. B. /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.Er unterstützt auch die Build-Flags des build-Befehls und bietet einen Parameter -exec, um anzugeben, welches Programm die Binärdatei ausführen soll. [arguments...] bezieht sich auf die Laufzeitparameter des Programms. Hier ein Beispiel:
package main
import (
"fmt"
"os"
)
var (
Version string
)
func main() {
fmt.Println(Version)
fmt.Println(os.Args[1:])
}Mit go run ausführen:
$ go run -ldflags="-X main.Version=$(git describe --always)" main.go hello
5e3fd7a
[hello]Insgesamt unterscheidet sich die Verwendung nicht wesentlich von go build, daher wird hier nicht weiter darauf eingegangen.
tool
Der tool-Befehl selbst hat keine Funktion. Seine Aufgabe ist es, Tools im cmd/-Verzeichnis direkt aufzurufen. Zum Beispiel ist cmd/compile der mitgelieferte Compiler. Mit go tool können Sie diese Tools direkt aufrufen, ohne die Binärdateien dieser Tools manuell ausführen zu müssen.
$ go tool -h
usage: go tool [-n] command [args...]Verwenden Sie den -n-Parameter, um alle unterstützten Befehlsparameter auszugeben:
$ go tool -n
addr2line
asm
buildid
cgo
compile
covdata
cover
doc
fix
link
nm
objdump
pack
pprof
test2json
trace
vetDiese Tools befinden sich im GOROOT/pkg/tool-Verzeichnis und sind nach Betriebssystem und CPU-Architektur gruppiert:
$ 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*Verwenden Sie das Format go doc cmd/command, um die Verwendung jedes Befehls anzuzeigen, zum Beispiel:
$ 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.
...Die vom cmd/compile unterstützten Flag-Parameter sind die zuvor erwähnten gcflags-Parameter. Der Unterschied zwischen go tool compile und go build besteht darin, dass ersterer nur für die Kompilierung verantwortlich ist und nur Dateien als Parameter akzeptiert. Letzterer kann Ordner, Pakete und Dateien als Parameter akzeptieren und führt nicht nur die Kompilierung des Quellcodes durch, sondern ist auch für das Verknüpfen von Dateien, das Entfernen unnötiger Dateien usw. verantwortlich. Ersterer ist ein Teil von Letzterem. Wir können die während des build-Prozesses ausgeführten Befehle ausgeben:
$ 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
...Während des Prozesses können Sie sehen, dass /golang/pkg/tool/windows_amd64/compile.exe aufgerufen wurde, was den Compiler aufruft. Neben compile gibt es viele weitere Tools, die aufgerufen werden können. Viele Go-Befehle sind tatsächlich nur Aliase für sie.
clean
Der clean-Befehl dient zum Entfernen von während des Kompilierungsprozesses generierten Objektdateien:
$ go clean -h
usage: go clean [clean flags] [build flags] [packages]
Run 'go help clean' for details.Er unterstützt folgende Flags:
-i: Entfernt die entsprechende Archiv- oder Binärdatei-n: Gibt die während des Bereinigungsprozesses auszuführenden Befehle aus, führt sie aber nicht tatsächlich aus-x: Gibt die während des Bereinigungsprozesses auszuführenden Befehle aus und führt sie aus-r: Entfernt rekursiv überimport path-cache: Entfernt allen vongo buildgenerierten Cache-testcache: Entfernt allen generierten Test-Cache-modcache: Entfernt allen heruntergeladenen Modul-Cache-fuzzcache: Entfernt den vonfuzz testgenerierten Cache.
Bei Verwendung von go tool compile wird der Compiler-Befehl direkt aufgerufen, ohne dass go build viele Nachbereitungen durchführt, was Objektdateien erzeugt. Zum Beispiel erzeugt die Ausführung des folgenden Befehls:
go tool compile -N -S -l main.goeine Datei namens main.o. Verwenden Sie den go clean-Befehl, um sie zu entfernen. Oder verwenden Sie den -n-Parameter, um die auszuführenden Befehle auszugeben:
$ 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.exeKompilierungs-Cache entfernen. Es löscht den im GOCACHE-Verzeichnis generierten Kompilierungs-Cache:
$ go clean -cache -n
rm -r /cache/00 /cache/01 /cache/02Entfernt den von fuzz test generierten Cache. Diese Caches werden standardmäßig im GOCACHE/fuzz/-Verzeichnis gespeichert:
$ go clean -fuzzcache -n
rm -rf /cache/fuzzfix
Zum Zeitpunkt der Erstellung dieses Artikels existiert die Go-Sprache seit zehn Jahren. Während des kontinuierlichen Updates und Änderns der Sprache können Inkompatibilitäten aufgrund von API-Änderungen auftreten. Der fix-Befehl wurde dafür entwickelt. Er erkennt veraltete APIs in Quelldateien und ersetzt sie durch neue APIs.
$ go fix -h
usage: go fix [-fix list] [packages]
Run 'go help fix' for details.Er unterstützt Ordner, Dateinamen und Verzeichnisse als Parameter. Er akzeptiert das -fix-Flag, um Parameter zu übergeben und anzugeben, welche Änderungen vorgenommen werden sollen. Verfügbare Werte können mit dem Befehl go tool fix -help angezeigt werden:
$ 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.Hier ein Beispiel: Der Quellcode verwendet das Paket golang.org/x/net/context:
package main
import (
"fmt"
"golang.org/x/net/context"
)
func main() {
background := context.Background()
fmt.Println(background.Err())
}Mit go fix korrigieren, um es durch das context-Paket der Standardbibliothek zu ersetzen. Wir können den folgenden Befehl verwenden:
$ go fix -fix context main.goOder Sie können es nicht ersetzen und stattdessen die Dateiänderungen vorher/nachher anzeigen:
$ 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() {Go existiert seit über zehn Jahren und hat nur neun verfügbare Ersatzparameter, was zeigt, dass die Kompatibilität recht gut erhalten wurde.
fmt
Der fmt-Befehl ist das mitgelieferte Formatierungstool von Go zum Formatieren von Go-Quelldateien.
$ go fmt -h
usage: go fmt [-n] [-x] [packages]
Run 'go help fmt' for details.Mit dem Befehl go doc gofmt können Sie die detaillierte Dokumentation anzeigen:
$ 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 verwendet Tab für Einrückungen und Leerzeichen für Ausrichtungen. Standardmäßig wird der formatierte Code in die Standardausgabe ausgegeben, nicht in die Originaldatei überschrieben. Der go fmt-Befehl verwendet tatsächlich den gofmt-Befehl, der eine eigenständige Binärdatei im GOROOT/bin-Verzeichnis ist:
$ ls $GOROOT/bin -1
go.exe*
gofmt.exe*Wenn Sie dem go fmt-Befehl das -n-Flag hinzufügen, können Sie die auszuführenden Anweisungen anzeigen:
$ go fmt main.go
/golang/bin/gofmt.exe -l -w main.goWie Sie sehen können, ist go fmt eigentlich nur ein Alias für gofmt -l -w. Der gofmt-Befehl hat folgende Parameter:
-d: Gibt Unterschiede zwischen formatiertem und originalem Code aus-e: Gibt alle Fehler aus-l: Gibt den Namen der geänderten Dateien aus-r: Wendet Formatierungsregeln an-s: Versucht, Code zu vereinfachen-w: Überschreibt die Quelldatei. Bei Fehlern wird das Backup wiederhergestellt.
Angenommen, es gibt folgende Quelldatei:
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("hello world!")}Mit dem -d-Parameter können Sie die Änderungen im Voraus anzeigen:
$ 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!")
+}Der -l-Parameter gibt den Namen der zu ändernden Dateien aus:
$ gofmt -l .
main.goBei Syntaxfehlern gibt der -e-Parameter detailliertere Informationen aus:
$ 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 wendet Änderungen auf die Quelldatei an:
$ gofmt -l -w .
main.go
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("hello world!")
}Sie können feststellen, dass gofmt als Formatierungstool überhaupt keine benutzerdefinierte Konfiguration bietet. Im Gegensatz dazu bietet der Formatierer prettify für JS-Code viele Konfigurationen zur Code-Formatierung. Dies zeigt die Haltung der Go-Offiziellen: Keine Individualisierung, der Code-Stil aller sollte möglichst konsistent sein. Zumindest hat es den Vorteil, dass Sie beim Lesen von Code nicht die Gewohnheiten anderer anpassen müssen. Allerdings gibt es tatsächlich eine benutzerdefinierte Option: die Ersetzungsregeln für formatierten Code. Regeln können benutzerdefiniert werden, das Format lautet:
pattern -> replacementZum Beispiel redundante Klammern entfernen:
(a) -> aDateiänderungen anzeigen:
$ 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!")
}Wie Sie sehen können, entfernt gofmt die redundanten Klammern.
get
Der get-Befehl ist absolut einer der am häufigsten verwendeten während der Go-Entwicklung. Seine Aufgabe ist es, den Quellcode指定 Pakets in das dem GOMODCACHE entsprechende Verzeichnis herunterzuladen.
$ go get -h
usage: go get [-t] [-u] [-v] [build flags] [packages]
Run 'go help get' for details.-u: Versucht, Neben- und Patch-Versionen des Pakets zu aktualisieren. Bei Hauptversionsänderungen wiev1->v2wird nicht aktualisiert.-t: Aktualisiert Abhängigkeitsversionen in Tests-v: Gibt kompilierte Pakete aus. Tatsächlich einer der Parameter vonbuild flags.
In früheren Zeiten war go get ähnlich wie go install. Es lud Pakete herunter und kompilierte sie. Mit der Entstehung und Verbesserung von Go-Modulen wurde diese Funktion allmählich eingestellt. Der get-Befehl wird jetzt am häufigsten zum Herunterladen und Auflösen von Abhängigkeiten für Go-Module verwendet. Daher können Sie sehen, dass der go get-Befehl auch build flags unterstützt. Wenn Sie versuchen, go get außerhalb eines Moduls wie go install zu verwenden, wird eine Warnung angezeigt, dass diese Verwendung veraltet ist:
$ 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'.Warum diese in der Dokumentation noch erwähnt werden, ist unbekannt. Wenn Sie den Quellcode des get-Befehls durchsehen, werden Sie feststellen, dass er die alten Flags noch enthält:
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
)Zurück zum Thema: Der get-Befehl lädt den Quellcode指定 Pakets in das lokale globale Abhängigkeitsverzeichnis herunter, also das GOCACHE-Verzeichnis, und zeichnet die Informationen in den Dateien go.mod und go.sum auf. Erstere ist für die Versionsaufzeichnung verantwortlich, Letztere für die SHA1-Prüfsumme zur Sicherheit. get basiert tatsächlich auf VCS, also dem lokalen Versionskontrollsystem. Insgesamt werden folgende unterstützt:
- git
- hg (Mercurial)
- bzr (Bazaar)
- svn
- fossil
Standardmäßig werden nur git und hg unterstützt. Kann in GOVCS konfiguriert werden, das Format lautet:
GOVCS=github.com:git,example.com:hg,*:git|hg,*:allGOVCS unterstützt nur git und hg als VCS. Die anderen drei müssen in GOPRIVATE konfiguriert werden.
Der go get-Befehl hat folgende Verwendungsmöglichkeiten. Kann die Abhängigkeitsadresse direkt als Parameter verwenden:
$ go get golang.org/x/netOder eine Version angeben:
$ go get golang.org/x/net@0.17.0Neueste Version angeben:
$ go get golang.org/x/net@latestVersion aktualisieren versuchen:
$ go get -u golang.org/x/netEine Abhängigkeit entfernen:
$ go get golang.org/x/net@noneDie oben genannten dienen zur Verwaltung normaler Abhängigkeiten. Er kann auch weniger normale Abhängigkeiten verwalten, z. B. die Go-Sprachversion aktualisieren:
$ 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.3Kann sogar die Go-Toolchain-Version aktualisieren:
$ go get toolchain@latestWenn Sie go get verwenden, um Go und die Toolchain-Version zu aktualisieren, installieren sie die neue Go-Version im GOMODCACHE/golang.org/-Verzeichnis:
$ ls $(go env GOMODCACHE)/golang.org -1
'toolchain@v0.0.1-go1.21.3.windows-amd64'/
x/Dann können Sie GOROOT manuell ändern, um zur指定 Version zu wechseln.
install
Der install-Befehl ist ähnlich wie der get-Befehl. Beide dienen zum Herunterladen von Drittanbieter-Abhängigkeiten. Der Unterschied besteht darin, dass get den Quellcode herunterlädt, während install den Quellcode zu einer für den lokalen Rechner ausführbaren Binärdatei kompiliert. Der Speicherpfad der Binärdatei ist zuerst im GOBIN-Verzeichnis, dann in GOPATH/bin. Die Hauptfunktion dieses Befehls ist das Herunterladen einiger öffentlicher CLI-Tools von Drittanbietern. Dank der Kompilierungsgeschwindigkeit und Portabilität von Go müssen keine Binärdateien heruntergeladen werden, sondern der Quellcode wird heruntergeladen und lokal kompiliert.
$ go install -h
usage: go install [build flags] [packages]
Run 'go help install' for details.Der install-Befehl akzeptiert Build-Flags und Paketnamen als Parameter. Bei aktiviertem gomod muss der Paketname eine Versionsnummer enthalten. Zum Beispiel den Delve-Debugger herunterladen:
$ 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/Zuerst wird der Quellcode in das GOMODCACHE-Verzeichnis heruntergeladen, was mit dem get-Befehl übereinstimmt. Dann wird in ein temporäres Arbeitsverzeichnis gewechselt, kompiliert, die Binärdatei in das GOPATH/bin-Verzeichnis verschoben und schließlich der temporäre Ordner gelöscht. Der install-Befehl hat eine Einschränkung: Das heruntergeladene Paket muss das Hauptpaket des Projekts sein, d. h. es muss eine main.go-Hauptdatei enthalten, andernfalls wird eine Fehlermeldung angezeigt, dass es nicht installiert werden kann. Zum Beispiel, Gin mit go install herunterladen:
$ 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 ist eine Web-Framework-Abhängigkeitsbibliothek, kein CLI-Tool, hat natürlich keine Hauptdatei, daher schlägt die Installation fehl.
list
Der list-Befehl listet Pakete指定 Positionen auf, eine pro Zeile, und unterstützt benutzerdefinierte formatierte Ausgabe. Er unterstützt viele Parameter. Voraussetzung für die Verwendung ist, dass er sich in einem gomod-unterstützenden Projekt befindet.
$ go list -h
usage: go list [-f format] [-json] [-m] [list flags] [build flags] [packages]
Run 'go help list' for details.Er unterstützt folgende Parameter:
-f: Formatierungsparameter-json: JSON-Format-Ausgabe-compiled: Zeigt alle vom Compiler kompilierten Pakete an-deps: Zeigt jeden Paketnamen und alle seine Abhängigkeiten an-test: Zeigt das Testpaket jedes Pakets an-e: Gibt bei fehlerhaften Paketen normal aus-find: Löst die Abhängigkeiten dieser Pakete nicht auf-export: Bei Verwendung dieses Parameters wird der Wert desPackage.Export-Felds der Struktur auf die Datei gesetzt, die die neuesten Exportinformationen指定 Pakets enthält, und derPackage.BuildID-Feldwert auf dieBuildIDdes Pakets. Hauptsächlich für formatierte Ausgabe.
Modulinformationsparameter:
-m: Gibt Module statt Pakete aus-versions: Zeigt alle verfügbaren Informationen eines Moduls an-retracted: Zeigt zurückgezogene Versionen eines Moduls an
Der [packages]-Parameter kann ein指定 Paketname, ein Ordner oder all sein, was überall bedeutet. Bei Verwendung des -m-Parameters bedeutet all alle aktuellen Modulabhängigkeiten.
Zum Beispiel, aktuelle Datei hat nur eine main.go-Datei mit nur einer Ausgabe "hello world". Nach Ausführung von go list -deps . gibt es alle von diesem Projekt bis fmt und seinen Referenzen abhängigen Pakete aus:
$ 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
golearnOder alle Modulabhängigkeiten des aktuellen Projekts ausgeben:
$ 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
Die Ausgabe des list-Befehls ist zeilenbasiert, jede Zeile ist ein Paket. Die Offiziellen bieten den Parameter -f für benutzerdefinierte Zeilenausgabe. Der akzeptierte Wert ist die von der template/text-Template-Engine definierte Template-Syntax. Zum Beispiel:
-f "package {{ .Dir }} {{ .Name }}"Jedes iterierte Paket wird als folgende Struktur übergeben. Alle Felder dieser Struktur können als Template-Parameter verwendet werden:
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
}Bei Iteration von Modulen wird folgende Struktur übergeben. Alle ihre Felder können ebenfalls als Template-Parameter verwendet werden:
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
}Alle Pakete anzeigen:
$ 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 toolModule anzeigen:
$ go list -m -f "mod {{.Path}} {{.Version}} {{.GoVersion}} {{.GoMod}}"
mod golearn 1.21.3 /golearn/go.modmod
go mod ist ein Befehl speziell zur Verwaltung von Go-Modulen.
$ 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.Es hat folgende Unterbefehle:
download: Lädt alle in dergo.mod-Datei angegebenen Abhängigkeiten in den lokalen Cache herunteredit: Bearbeitet diego.mod-Datei. Die bereitgestellte CLI-Schnittstelle ist hauptsächlich für andere Tools oder Skripte gedacht.init: Initialisiert ein gomod-Projekt im aktuellen Verzeichnistidy: Lädt fehlende Abhängigkeiten herunter, entfernt ungenutzte Abhängigkeitengraph: Gibt Abhängigkeitsdiagramm ausverify: Überprüft lokale Abhängigkeitenwhy: Erklärt, warum diese Module benötigt werdenvendor: Exportiert Projektabhängigkeiten in das vendor-Verzeichnis
init
$ go help mod init
usage: go mod init [module-path]Der init-Befehl dient zur Initialisierung eines gomod-Projekts. Der einzige Parameter ist der Modulpfad, der später als Grundlage dient, wenn andere Ihre Abhängigkeiten herunterladen möchten. Die Namenskonvention lautet im Allgemeinen:
domain_name/user_name/repo_nameZum Beispiel, wenn die meisten Projekte auf github gehostet werden, könnte es sein:
github.com/jack/gotourEs wird nicht empfohlen, spezielle Symbole als Modulpfad zu verwenden. Hier ein Anwendungsbeispiel:
$ 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]Der tidy-Befehl entfernt ungenutzte Abhängigkeitselemente aus go.mod, also nicht referenzierte Abhängigkeiten, und lädt referenzierte, aber nicht vorhandene Abhängigkeiten herunter. Er unterstützt folgende Parameter:
-v: Gibt gelöschte Modulabhängigkeiten aus-e: Ignoriert Fehler während des Prozesses und fährt fort-x: Gibt den Ausführungsprozess aus-go=version: Aktualisiert die Go-Version in dergo.mod-Datei-compact=version: Behält alle zusätzlichen Prüfsummen bei, die von der angegebenen Haupt-Go-Version benötigt werden, um das Moduldiagramm erfolgreich zu laden. Wenn dergo-Befehl dieser Version ein importiertes Paket aus einer anderen Modulversion lädt, führt tidy zu einem Fehler. Dieser Parameter wird im Allgemeinen selten verwendet und tritt normalerweise nur bei Versionsänderungen auf. Weitere Informationen finden Sie in dieser StackOverflow-Antwort: go modules - go mod tidy error message: "but go 1.16 would select" - Stack Overflow
Hier ein Anwendungsbeispiel:
$ 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]Obwohl der Name des download-Befehls als "Herunterladen" übersetzt wird, lädt er nur Abhängigkeiten in den lokalen Abhängigkeits-Cache herunter und ändert die go.mod-Datei nicht. Seine Funktion besteht darin, Abhängigkeiten im Voraus in den lokalen Dateicache herunterzuladen. Wenn Sie eine bestimmte Abhängigkeit herunterladen möchten, wird empfohlen, go get oder go mod tidy zu verwenden.
Hier einige Anwendungsbeispiele:
$ 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)Ohne Parameter lädt es alle im go.mod-Verzeichnis vorhandenen, aber nicht im lokalen Abhängigkeits-Cache vorhandenen Abhängigkeiten herunter. Wenn nichts herunterzuladen ist, gibt es aus:
go: no module dependencies to downloadedit
$ go help mod edit
usage: go mod edit [editing flags] [-fmt|-print|-json] [go.mod]edit ist eine CLI-Schnittstelle zum Ändern der go.mod-Datei, die normalerweise von anderen Programmen verwendet wird. Einige Editor-IDEs verwenden diese Befehle, um gomod-Unterstützung bereitzustellen. Es unterstützt folgende Parameter:
-module: Ändert den Modulpfad-go=version: Ändert die erwartete Go-Version-require=path@version: Fügt eine Abhängigkeit hinzu-droprequire=path@version: Entfernt eine Abhängigkeit-exclude=path@version: Fügt eine ausgeschlossene Abhängigkeit hinzu-dropexclude=path@version: Entfernt eine ausgeschlossene Abhängigkeit-replace=old@version=new@version: Fügt eine ersetzende Abhängigkeit hinzu-dropreplace=old@version: Entfernt eine ersetzende Abhängigkeit-retract=version: Fügt einen Versionsrückzug hinzu-dropretract=version: Entfernt einen Versionsrückzug
Weitere Parameter zur Anzeige:
-print: Gibt den Dateiinhalt aus-json: Gibt im JSON-Format aus
Zum Beispiel:
$ 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]Der graph-Befehl gibt das Abhängigkeitsdiagramm des aktuellen Projekts aus. Die Lesbarkeit ist schlecht und meist nicht für Menschen gedacht. Die Ergebnisse werden normalerweise verarbeitet und visuell dargestellt. Jede Zeile ist eine Abhängigkeit, das Format lautet:
引用方 被引用方Zum Beispiel:
golearn go@1.21.3Es unterstützt zwei Parameter:
-go=version: Lädt das Abhängigkeitsdiagramm mit der angegebenen Go-Version. Der Wert darf nicht kleiner als die Version in dergo.mod-Datei sein.-x: Zeigt die während des Prozesses ausgeführten Befehle.
Hier ein einfaches Anwendungsbeispiel:
$ 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 war eine Alternative zu gopath vor der Einführung von gomod. Jedes Go-Projekt hatte ein vendor-Verzeichnis, das jede Projektabhängigkeit separat im Format domain/user/project speicherte, ähnlich wie das aufgeblähte node_module von Node.js, wo jede Projektabhängigkeit separat gespeichert wird. Diese Abhängigkeitsverwaltungsmethode erscheint heute tatsächlich ziemlich dumm, aber damals gab es keine bessere Lösung. Der Grund für die Beibehaltung von vendor ist, dass Go sein Abwärtskompatibilitätsversprechen einhält. Einige alte Projekte, einschließlich des Go-Quellcodes, verwenden möglicherweise noch vendor.
Zurück zum Thema: vendor ist ein Unterbefehl von go mod, der globale Abhängigkeiten, auf die das aktuelle Modul verweist, in das vendor-Verzeichnis exportieren kann.
$ go mod vendor -h
usage: go mod vendor [-e] [-v] [-o outdir]
Run 'go help mod vendor' for details.Es hat folgende Parameter:
-o: Gibt den Ausgabe-Pfadordner an-v: Gibt jede Abhängigkeit aus-e: Fährt bei Fehlern fort, ohne zu beenden
Hier ein Beispiel. Zuerst mit go list -m all die vom aktuellen Projekt referenzierten Abhängigkeiten anzeigen:
$ 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.1In das aktuelle vendor-Verzeichnis exportieren:
$ 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.v3Die exportierte Verzeichnisstruktur lautet wie folgt:
└─vendor
├─github.com
│ ├─davecgh
│ │ └─go-spew
│ │ └─spew
│ ├─pkg
│ │ └─errors
│ ├─pmezard
│ │ └─go-difflib
│ │ └─difflib
│ └─stretchr
│ └─testify
│ └─assert
└─gopkg.in
| └─yaml.v3
|
|--modules.txtDie modules.txt darin ist die Datei, die alle Abhängigkeitselemente beschreibt, ähnlich wie die aktuelle go.mod.
verify
$ go help mod verify
usage: go mod verifyDieser Befehl überprüft, ob die Projektabhängigkeiten seit dem Herunterladen in den lokalen Speicher geändert wurden. Wenn kein Problem vorliegt, gibt er all modules verified aus:
$ go mod verify
all modules verifiedAndernfalls meldet er, wo Änderungen aufgetreten sind, und beendet den Befehl mit einem nicht normalen Status. Zum Beispiel:
$ 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...Erklärt, warum dieses Paket benötigt wird, gibt tatsächlich das Abhängigkeitsdiagramm darüber aus. Zum Beispiel:
$ go mod why gorm.io/gorm
# gorm.io/gorm
golearn
gorm.io/gormStandardmäßig wird nur der Import von main analysiert. Mit dem -m-Parameter kann die Importsituation jedes Pakets analysiert werden.
work
Der Befehl work ist ein lokales Entwicklungstool für Go-Multi-Modul-Verwaltung.
$ 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
Der Unterbefehl init dient zur Initialisierung eines Workspace. Dieser Befehl erstellt eine Datei namens go.work:
$ go work init -h
usage: go work init [moddirs]
Run 'go help work init' for details.Akzeptiert den Parameter [moddirs], um anzugeben, welche Module in die Verwaltung einbezogen werden sollen, zum Beispiel:
$ go work init ./service ./apiuse
Der Unterbefehl use dient zum Hinzufügen von Modulverzeichnissen zur Verwaltung in 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.Akzeptiert [moddirs] als Parameter. Ein -r bedeutet, dass im [moddirs]-Pfad rekursiv nach Modulen gesucht wird, zum Beispiel:
$ go work use -r ./oss-api ./multi_modulesedit
Die Funktion des Unterbefehls edit ist dieselbe wie bei go mod edit. Beide sind für CLI-Schnittstellen für andere Tools und Skripte gedacht.
$ 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 directoriesParameter sind wie folgt:
-fmt: Formatierung dergo.work-Datei-use,-dropuse: Hinzufügen und Entfernen von Modulpfaden-replace=old[@v]=new[@v],-dropreplace=old[@v]=new[@v]: Zum Hinzufügen und Entfernen zu ersetzender Module-go,-toolchain=name: Go-Version angeben und zu verwendende Toolchain angeben-print: Gibt die letzten Änderungen aus, ohne in die Datei zurückzuschreiben-json: Gibt im JSON-Format aus. Kann nicht mit-printgleichzeitig verwendet werden. Die entsprechende Typstruktur lautet wie folgt:gotype 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 }
Einige Anwendungsbeispiele sind wie folgt, formatierte Ausgabe:
$ go work edit -fmt -print
go 1.22.0
use (
./ab/cd
./auth
./user
)JSON-Ausgabe:
$ go work edit -fmt -json
{
"Go": "1.22.0",
"Use": [
{
"DiskPath": "./ab/cd"
},
{
"DiskPath": "./auth"
},
{
"DiskPath": "./user"
}
],
"Replace": null
}sync
Der Unterbefehl sync dient zum Synchronisieren der Modulliste in go.work zurück zu den einzelnen Modulen im Workspace.
$ go help work sync
usage: go work sync
Sync syncs the workspace's build list back to the
workspace's modulesDieser Prozess findet hauptsächlich nach Abschluss der lokalen Entwicklung statt, wenn die einzelnen Module bereits veröffentlicht wurden. Zu diesem Zeitpunkt verwendet sync, um die go.mod-Dateien aller Module im Workspace basierend auf den Abhängigkeitsbeziehungen der einzelnen Module zu aktualisieren, sodass wir sie nicht manuell aktualisieren müssen.
vendor
Der vendor-Befehl erstellt eine Kopie aller von Modulen im Workspace abhängigen Bibliotheken im vendor-Verzeichnis.
$ go work help vendor
usage: go work vendor [-e] [-v] [-o outdir]Funktion wie go mod vendor, wird hier nicht weiter erläutert.
vet
Der Befehl vet ist ein statisches Fehlerprüfungstool für Go-Quellcode, ähnlich wie Lint-Tools in anderen Sprachen, z. B. 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.Zuerst ein einfaches Beispiel. Es gibt folgenden Quellcode:
$ cat main.go
package main
import "fmt"
func main(){
fmt.Println("hello world!"
}Ohne Parameter im selben Verzeichnis go vet ausführen:
$ go vet
vet: ./main.go:6:28: missing ',' before newline in argument list (and 1 more errors)vet meldet, welche Datei, welche Zeile und welches Problem aufgetreten ist. Es unterstützt Build-Flags als Parameter, z. B. -n und -x, sowie Pakete, Ordner und Dateinamen als Parameter:
$ go vet .
$ go vet main.go
$ go vet ./cmd
$ go vet runtimeMit folgendem Befehl können Sie detailliertere Parameter und Erklärungen anzeigen:
$ 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
......Der Befehl go tool vet kann nicht direkt zur Code-Überprüfung verwendet werden. Sie sollten go vet verwenden. Die [vet flag]-Parameter von go vet unterstützen das Einstellen von Code-Analysegeräten. Verfügbare Werte sind:
asmdecl Prüft, ob Assembler-Dateien nicht mit Go-Deklarationen übereinstimmen
assign Prüft auf nutzlose Zuweisungen
atomic Prüft auf häufige Fehler bei der Verwendung von sync/atomic
bools Prüft auf häufige Fehler bei booleschen Operatoren
buildtag Prüft //go:build und // +build Direktiven
cgocall Prüft auf Verstöße gegen cgo-Zeigerübergaberegeln
composites Prüft uninitialisierte zusammengesetzte Strukturen wie map, chan
copylocks Prüft, ob eine Wertkopie von Sperren auftritt
directive Prüft Go-Toolchain-Direktiven
errorsas Prüft, ob Nicht-Zeiger- oder Nicht-Error-Typen an errors.As übergeben werden
framepointer Prüft, ob optimierter Assembler-Code den Frame-Pointer löscht, bevor er gespeichert wird
httpresponse Prüft auf falsche Verwendung von httpresponse
ifaceassert Prüft Interface-zu-Interface-Typbehauptungen
loopclosure Probleme mit Referenzen auf Schleifenvariablen
lostcancel context.WithCancel ohne Verwendung der Cancel-Funktion
nilfunc Prüft auf nutzlose Vergleiche zwischen Funktionen und nil
printf Prüft, ob printf-Formatierungsparameter korrekt sind
shift Prüft auf Schiebeoperationen, die der Integer-Breite entsprechen oder diese überschreiten
sigchanyzer Prüft auf ungepufferte chan os.Signal
slog Prüft auf ungültige strukturierte Protokollaufrufe
stdmethods Prüft, ob Signaturen bekannter Schnittstellenmethoden korrekt sind
stringintconv Prüft String-zu-Integer-Konvertierung
structtag Prüft, ob Struct-Tags korrekt sind
testinggoroutine Prüft, ob testing.Fatal in einer Goroutine im Test aufgerufen wird
tests Prüft auf häufige Fehler bei Tests und Beispielen
timeformat Prüft, ob das Zeitformat bei (time.Time).Format oder time.Parse korrekt ist
unmarshal Übergibt Nicht-Zeiger- oder Nicht-Schnittstellentypen an unmarshal
unreachable Prüft auf unerreichbaren Code
unsafeptr Prüft auf falsche Konvertierung von uintptr zu unsafe.Pointer
unusedresult Prüft auf nicht verwendete FunktionsrückgabewerteEs handelt sich um Analysegeräte, die auf einen bestimmten Punkt analysieren. Zum Beispiel analysiert das timeformat-Analysegerät, ob der Aufrufformat von time.Format der korrekten Syntax entspricht. Standardmäßig sind alle oben genannten Analysegeräte aktiviert. Zum separaten Aktivieren verwenden Sie folgendes Format:
$ go vet -timeformat main.goSeparat deaktivieren:
$ go vet -timeformat=false main.goDer Quellcode dieser Analysegeräte befindet sich in cmd/vendor/golang.org/x/tools/go/analysis/passes. Jedes Analysegerät ist eine häufige Fehlerquelle in Go, daher wird dringend empfohlen, den vet-Befehl zur Code-Überprüfung zu verwenden. Darüber hinaus unterstützt es einige andere Flag-Parameter:
-V: Nur Version ausgeben und beenden-json: Im JSON-Format ausgeben-c=n: Zeigt die Anzahl der Konfliktzeilen im Kontext an (scheint keine Wirkung zu haben)
Es gibt auch externe Analysegeräte, z. B. shadows, das für die Erkennung von Variablen-Shadowing-Problemen bei Kurzvariablennamen verantwortlich ist. Da es extern ist, muss es mit go install heruntergeladen werden:
$ go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latestVerwendungsformat:
$ 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.Der test-Befehl ist der Befehl in der Go-Toolchain, der Testfunktionen bereitstellt. Diese Funktion ist sehr wichtig. Für eine Software sind umfassende Tests unverzichtbar. Hier wird nur kurz vorgestellt, wie der test-Befehl verwendet wird. Für weitere Informationen zu Tests besuchen Sie: 测试
Neben den Kompilierungsparametern des build-Befehls unterstützt test auch folgende Parameter:
-args: Programm-Eingabeparameter-c: Kompiliert die Test-Binärdatei des aktuellen Pakets in das aktuelle Verzeichnis, führt sie aber nicht aus. Benennung im Formatpkg.test-exec: Führt vor Testbeginn einige andere Befehle aus-json: Test-Ausgabestil wird JSON-o: Gibt den Pfadnamen der Test-Binärdatei an
Es unterstützt auch viele testflag. Mit dem help-Befehl alle testflag anzeigen:
$ go help testflag
`go test` 命令既接受作用于 `go test` 本身的标志,
也接受作用于生成的测试二进制文件的标志。
`go test` 命令识别以下标志,并用于控制任何测试的执行:
-bench regexp
-benchtime t
-count n
......Einführung einiger häufig verwendeter:
-v: Gibt Testergebnisse jedes Use-Cases aus.-timeout duration: Test-Ausführungs-Timeout-skip regexp: Überspringt指定 Test-Use-Cases-short: Lässt lang laufende Test-Use-Cases kürzer laufen-shuffle: Mischt die Ausführungsreihenfolge aller Test-Use-Cases-run regexp: Führt指定 Test-Use-Cases aus-list regexp: Listet jeden Test-Use-Case auf-cpu 1,2,4: Gibt CPU-Anzahl an-count n: Gibt an, wie oft jeder Test-Use-Case ausgeführt werden soll
Die einfachste Verwendung ist ohne Parameter. Es führt alle Test-Use-Cases im aktuellen Paket aus und gibt Ergebnisse aus:
$ ls *_test.go
hello_test.go
$ go test
PASS
ok golearn 0.522sEine bestimmte Testdatei angeben:
$ go test hello_test.go
ok command-line-arguments 0.041sMit dem -v-Parameter können detailliertere Ausgaben angezeigt werden. Es ist sehr häufig verwendet:
$ go test -v hello_test.go
=== RUN TestHello
hello_test.go:6: hello world!
--- PASS: TestHello (0.00s)
PASS
ok command-line-arguments 0.041sEinen bestimmten Test-Use-Case angeben:
$ go test -v -run TestHello
=== RUN TestHello
hello_test.go:6: hello world!
--- PASS: TestHello (0.00s)
PASS
ok golearn 0.028sWährend des Tests gibt es zwei Modi für den test-Befehl. Zuerst der Ordner-Modus: Wenn der test-Befehl ohne package-Parameter ausgeführt wird, wird er im Ordner-Modus ausgeführt. Zum Beispiel folgende Befehle:
$ go test
$ go test -vIn diesem Modus ist der Test-Cache deaktiviert. Der andere Modus ist der Listen-Modus: Wenn der package-Parameter nicht leer ist, wird im Listen-Modus getestet. Der Unterschied zum ersteren besteht darin, ob der Test-Cache aktiviert ist. Zum Beispiel folgende:
$ go test -v .
$ go test -v ./...
$ go test .
$ go test -v net/httpIm Listen-Modus kompiliert Go die Testdateien jedes Pakets指定 Pakets zu Binärdateien und führt sie aus. Um wiederholte Tests zu vermeiden, cached Go standardmäßig die Ergebnisse. Bei der zweiten Ausführung wird nicht neu kompiliert. Bei Verwendung folgender Parameter wird der Cache standardmäßig aktiviert:
-benchtime-cpu-list-parallel-runshort-timeout-failfast-v
Bei Verwendung anderer Parameter als dieser kann der Cache deaktiviert werden. Die offiziell empfohlene Methode ist die Verwendung von -count=1, um den Cache zu deaktivieren. Zum Beispiel:
$ go test -v -count=1 ./...Anweisungen
Im Gegensatz zu Befehlen sind Go-Anweisungen hartkodiert in Quelldateien vorhanden. Sie haben einen anderen, eher technischen Namen: Compiler-Direktiven (Pragma-Direktiven).
Compiler und Linker ändern ihr Verhalten aufgrund dieser Direktiven, um die Kompilierung zu steuern, ähnlich wie Makros in C. Allerdings sind nicht alle Anweisungen zur Beeinflussung der Kompilierung gedacht. Einige dienen anderen funktionalen Verhaltensweisen. Zum Beispiel wird die generate-Anweisung normalerweise für Code-Generierungsfunktionen verwendet. Diese Anweisungen existieren normalerweise in Form von Kommentaren und haben das Präfix //go:, ohne Leerzeichen dazwischen, z. B. die //go:generate-Anweisung. Alle Anweisungstypen sind insgesamt in zwei Kategorien unterteilt:
- Funktionale Anweisungen: Dies sind von Go bereitgestellte funktionale Anweisungen, die frei verwendet werden können, z. B.
generate,embed,build. - Compiler-Anweisungen: Diese Anweisungen müssen mit Vorsicht verwendet werden. Unsachgemäße Verwendung kann zu unvorhersehbaren Ergebnissen führen.
Mit Ausnahme funktionaler Anweisungen können die meisten Anweisungen nur auf Funktionssignaturen wirken. Für Compiler-Anweisungen können Sie den Befehl go doc compile ausführen, um ihre Anweisungen anzuzeigen. Für alle Anweisungen finden Sie Informationen in cmd/compile/internal/ir/node.go: 440.
generate
$ go help generate
usage: go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]Die generate-Anweisung ist, wie der Name schon sagt, mit Generierung verbunden. Normalerweise dient sie zur Ausführung von Befehlen, die Code generieren und Quellcode aktualisieren. Tatsächlich kann sie jedoch beliebige Befehle ausführen. Im Gegensatz zu anderen Anweisungen gibt es einen speziellen Befehl, der alle in Quelldateien befindlichen generate-Anweisungen ausführen kann. Sie kann Dateinamen oder Paketnamen als Eingabeparameter verwenden, um anzugeben, welche Dateien generate-Anweisungen ausgeführt werden sollen. Hier sind ihre anderen Parameter:
-run=regex: Führt指定generate-Anweisungen aus-skip=regex: Überspringt指定generate-Anweisungen-n: Gibt die auszuführenden Befehle aus-x: Gibt die während des Prozesses ausgeführten Befehle aus-v: Gibt die verarbeiteten Dateien aus
Darüber hinaus unterstützt die in generate-Anweisungen ausgeführte Befehle folgende eingebaute Parameter:
$GOARCH: CPU-Architektur$GOOS: Betriebssystem$GOFILE: Dateiname$GOLINE: Zeilennummer$GOPACKAGE: Paketname$GOROOT: Go Root$DOLLAR: Dollar-Zeichen$PATH: PATH-Umgebungsvariable
Ein Beispiel, nur ein Kommentar ohne Code:
package main
//go:generate echo "hello world!"Befehl ausführen:
$ go generate .
hello world!Dieses Beispiel führt einen Go-Befehl aus:
package main
//go:generate go versionBefehl ausführen:
$ go generate .
go version go1.21.3 windows/amd64Die generate-Anweisung kann zur Ausführung beliebiger Befehle verwendet werden, z. B. Swagger zur Generierung von API-Dokumenten oder Wire zur Generierung von IOC-Code. Allerdings ist diese Anweisung nicht für besonders komplexe Befehle geeignet. Sie eignet sich für kurze Befehle. Bei komplexen Anforderungen können Skripte oder Makefile als Ersatz verwendet werden.
embed
Die embed-Anweisung wurde in Version 1.16 hinzugefügt. Ihre Funktion besteht darin, statische Dateien zusammen in die Binärdatei zu packen, z. B. HTML-Vorlagen. Das Format lautet wie folgt:
//go:embed patternpattern kann ein Glob-Ausdruck, ein Ordner oder eine bestimmte Datei sein. Ein Beispiel:
package main
import "embed"
//go:embed *
var static embed.FSDie embed-Anweisung erfordert, dass sie sich über einer globalen Variable vom Typ embed.FS befindet. Beachten Sie, dass es eine globale Variable sein muss. Die Verwendung erfordert den Import des embed-Pakets. In diesem Beispiel repräsentiert *, dass alle Dateien im aktuellen Ordner in die Binärdatei gepackt werden. Allerdings werden Ordner, die mit . beginnen, nicht允许.
Das folgende Beispiel zeigt das Lesen von Inhalten aus eingebetteten Dateien:
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))
}Es hat nur drei Methoden. Die Verwendung unterscheidet sich nicht von einem normalen Dateisystem. Da es das io/Fs-Interface implementiert, kann es auch als Fs-Objekt übergeben werden:
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)Das folgende Beispiel zeigt das Einbetten von HTML-Dateien über die embed-Anweisung und den Zugriff über einen HTTP-Dienst:
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)
}Ergebnis nach访问:
$ 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>Die embed-Anweisung unterstützt auch, dass der Typ der globalen Variable []byte sein kann. Zum Beispiel:
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)
}Der erzielte Effekt ist ähnlich wie im vorherigen Beispiel:
$ 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
Im Abschnitt build-编译控制 wurde die Verwendung der // +build-Anweisung zur Steuerung des Kompilierungsverhaltens erläutert. Die //go:build-Anweisung ist neu in Version 1.17 und soll die vorherige Anweisung ersetzen. Allerdings sind wir jetzt bei Version 1.21, und sie wurde noch nicht ersetzt. Schätzungsweise werden sie in Zukunft koexistieren. Zur neuen Anweisung gibt es auch eine offizielle Dokumentation: build constraints. Ihre Funktion unterscheidet sich nicht von der vorherigen, aber die Syntax ist strenger und unterstützt boolesche Ausdrücke. Ein Beispiel:
//go:build (linux && 386) || (darwin && !cgo)
package pkg_nameDiese Methode ist viel lesbarer als die ursprüngliche.
line
Die line-Anweisung beeinflusst die Zeilennummer, Spaltennummer und den Dateinamen der nächsten Zeile. Ihre Wirkung beschränkt sich darauf und wird meist zur Debugging von Fehlern verwendet. Zum Beispiel ändert sie bei einem Fehler die vom Compiler ausgegebenen Informationen:
package main
var a undefinedType
func main() {
}Normalerweise gibt der Compiler aus:
.\main.go:3:7: undefined: undefinedTypeAber mit der line-Anweisung sieht es anders aus:
package main
//line abc.go:10:100
var a undefinedType
func main() {
}Dann lautet die Ausgabe:
abc.go:10:106: undefined: undefinedTypeAufgrund historischer Gründe ist die line-Anweisung auch die einzige Anweisung, deren Verwendung sich von anderen Anweisungen unterscheidet. Das Format lautet:
//line filename:line:columnWie Sie sehen können, benötigt sie kein go: als Präfix.
linkname
Diese Anweisung kann verwendet werden, um Funktionen oder globale Variablen anderer Pakete zu verknüpfen, selbst wenn sie private Typen sind. Diese Operation tritt häufig in der Standardbibliothek, insbesondere in runtime, auf. Einige Funktionen haben keinen Funktionskörper und werden auf diese Weise implementiert. Ein anderer Teil der Funktionen mit leerem Funktionskörper wird durch Assembly implementiert. Hier ist die Verwendung. Das Format lautet:
//go:linkname 链接类型名称 被链接的类型Und vor der Verwendung muss beispielsweise das unsafe-Paket importiert werden. Ein einfaches Beispiel für die Verknüpfung privater Typen in der Standardbibliothek:
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")))
}Ausgabe:
15395306441938000233Es verknüpft die private Funktion runtime.memhash mit unserer selbst deklarierten Funktion. Diese Funktion hat keinen Funktionskörper, nur eine Signatur, und dient nur als Träger. memhash berechnet den Hash-Wert basierend auf dem Speicher, gegeben einem Zeiger, Hash-Seed und Speicher-Offset. Dieser Verknüpfungsprozess wird zur Kompilierzeit abgeschlossen.
Wenn es nicht die Standardbibliothek ist, ist die Situation etwas anders. Zum Beispiel gibt es eine test-Funktion im example-Paket. Vor der Verknüpfung muss dieses Paket anonym importiert werden:
package example
// 一个私有类型,外界无法访问。
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())
}Ausgabe:
aWie Sie sehen können, war die Verknüpfung erfolgreich. Diese Methode kann das Go-Modulsystem umgehen und beliebig agieren. Es wird jedoch nicht empfohlen, sie großflächig zu verwenden, es sei denn, Sie wissen, was Sie tun.
noinline
Die noinline-Anweisung bedeutet, dass eine Funktion keine Inline-Optimierung erlaubt, selbst wenn sie sehr einfach ist. Ein einfaches Beispiel:
package main
func val() string {
return "val"
}
func main() {
var c = val()
_ = c
}val ist eine sehr einfache Funktion, die einen String-Literal zurückgibt. Da sie zu einfach ist und das Ergebnis immer vorhersehbar ist, wird sie beim Kompilieren vom Compiler wie folgt optimiert:
package main
func main() {
var c = "val"
_ = c
}Schauen wir uns die Assembly-Form an. Wie Sie sehen können, wurde kein Aufruf der val-Funktion gefunden:
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)
RETAls Nächstes fügen wir die noinline-Anweisung hinzu:
package main
//go:noinline
func val() string {
return "val"
}
func main() {
var c = val()
_ = c
}Schauen wir uns erneut die Assembly-Form an:
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
RETDieses Mal können Sie deutlich den main.val-Aufruf sehen, was genau die Funktion der noinline-Anweisung ist: Verhindern von Funktions-Inlining während der Compiler-Optimierung.
nosplit
Die nosplit-Anweisung überspringt die Stack-Overflow-Erkennung. Da das Go-Nebenläufigkeits-Scheduler-Modell ein präemptives Scheduler-Modell ist, kann diese Anweisung verwendet werden, wenn eine Funktion sehr low-level-Code ausführt und andere Goroutinen beim Aufruf dieser Funktion nicht geeignet sind, präemptiert zu werden:
//go:nosplit
func nospilitFn()Nach Verwendung dieser Anweisung findet kein Stack-Wachstum mehr statt.
noescape
noescape, wie der Name schon sagt, hat mit Escape zu tun. Es bedeutet, dass die aktuelle Funktion kein Memory-Escape-Verhalten auftritt. Nach der Ausführung werden alle Ressourcen回收, und diese Funktion muss nur eine Signatur ohne Funktionskörper haben. In diesem Fall wird die Implementierung der Funktion normalerweise durch Assembly realisiert.
Zum Beispiel verwendet das zuvor verwendete memhash diese Anweisung:
//go:noescape
//go:linkname memhash runtime.memhash
func memhash(p unsafe.Pointer, h, s uintptr) uintptrAuf diese Weise führt der Compiler keine Escape-Analyse durch. Voraussetzung ist, dass Sie sicherstellen müssen, dass kein Escape auftritt. Wenn es doch auftritt, sind die Folgen unbekannt.
uintptrescapes
Die uintptrescapes-Anweisung bedeutet, dass uintptr-Typ-Parameter in dieser Funktion in Zeigerwerte konvertiert wurden und auf den Heap escaped sind und am Leben gehalten werden müssen. Diese Anweisung wird im Allgemeinen für einige low-level-Systemaufrufe verwendet. In den meisten Fällen muss sie nicht verstanden werden:
//go:uintptrescapes
func nospilit(ptr uintptr) uintptrFrüher gab es eine notinheaps-Anweisung, die angab, dass ein Typ keinen Speicher auf dem Heap allozieren darf. Sie wurde in einer unbekannten Version entfernt.
norace
Die norace-Anweisung bedeutet, dass der Speicherzugriff einer Funktion keine Race-Analyse erfordert. Wird normalerweise verwendet, wenn low-level-Code ausgeführt wird und keine Race-Analyse geeignet ist:
//go:norace
func low_level_code(ptr uintptr) uintptrTIP
Einige Anweisungen sind auf die Verwendung durch das runtime-Paket beschränkt und können extern nicht verwendet werden. Sie betreffen tiefere Dinge. Weitere Informationen finden Sie unter Runtime-only compiler directives.
