Baris Perintah

Perintah di Go mencakup satu set toolchain lengkap yang mencakup dokumentasi, pemformatan, pemeriksaan kode, kompilasi, pengujian, manajemen dependensi, dan berbagai aspek pengembangan Go.
bug Laporkan kerentanan
build Kompilasi paket dan dependensi
clean Hapus file objek
doc Tampilkan dokumentasi dalam kode sumber
env Lihat informasi variabel lingkungan Go
fix Perbaiki masalah kompatibilitas API akibat perubahan versi go
fmt Pemformatan kode sumber
generate Pembuatan kode
get Tambahkan dependensi
install Instal dan kompilasi paket
list Perintah daftar paket/modul
mod Perintah pemeliharaan modul
work Perintah pemeliharaan workspace
run Kompilasi dan jalankan
test Uji
tool Jalankan alat go yang ditentukan
version Tampilkan informasi versi go
vet Pindai dan tampilkan masalah potensial dalam kode sumberArtikel ini hanya menjelaskan penggunaan mereka secara sederhana, semua konten mengacu pada dokumentasi resmi, jika ingin mempelajari lebih detail silakan kunjungi cmd/go.
help
Perintah pertama yang harus dikenali adalah perintah help, yang dapat digunakan untuk membaca penggunaan perintah. Ada dua cara penggunaan, jika ingin mendapatkan informasi penggunaan singkat, Anda dapat menambahkan flag -h setelah perintah yang ditentukan, misalnya
$ go env -h
usage: go env [-json] [-u] [-w] [var ...]
Run 'go help env' for details.go akan menampilkan penggunaan perintah dengan singkat, juga memberi tahu bahwa untuk mendapatkan informasi lebih detail perlu menggunakan perintah help
$ go help env
usage: go env [-json] [-u] [-w] [var ...]
Env prints Go environment information.
By default env prints information as a shell script
(on Windows, a batch file). If one or more variable
names is given as arguments, env prints the value of
each named variable on its own line.
The -json flag prints the environment in JSON format
instead of as a shell script.
The -u flag requires one or more arguments and unsets
the default setting for the named environment variables,
if one has been set with 'go env -w'.
The -w flag requires one or more arguments of the
form NAME=VALUE and changes the default settings
of the named environment variables to the given values.
For more about environment variables, see 'go help environment'.Manfaatkan perintah help dengan baik, melalui itu Anda bisa mendapatkan banyak informasi tentang perintah.
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 exportedPerintah doc akan menampilkan komentar dokumentasi untuk paket, konstanta, fungsi, tipe, variabel, metode, atau bahkan field struct yang ditentukan. Tanpa parameter apa pun, akan menampilkan komentar paket saat ini
$ go docJuga dapat menentukan paket tertentu untuk dilihat, misalnya melihat dokumentasi paket runtime
$ go doc runtime
package runtime // import "runtime"
Package runtime contains operations that interact with Go's runtime system,
such as functions to control goroutines. It also includes the low-level type
information used by the reflect package; see reflect's documentation for the
programmable interface to the run-time type system.
......Atau tipe tertentu
$ 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.
...Atau fungsi tertentu
$ 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.Memiliki flag berikut yang umum digunakan
-u: Lihat tipe privat-all: Lihat semua dokumentasi paket yang ditentukan-short: Hanya deskripsi singkat satu baris-src: Tampilkan kode sumber-cmd: Untuk beberapa paket yang merupakan perintah go, juga tampilkan dokumentasi kode di dalam paket.
Misalnya melihat variabel runtime.inf, yang merupakan variabel yang tidak diekspor
$ go doc -u runtime.inf
package runtime // import "runtime"
var inf = float64frombits(0x7FF0000000000000)Manfaatkan perintah doc dengan baik dapat membantu Anda membaca dokumentasi dengan lebih mudah.
Cara lain untuk membaca dokumentasi perintah adalah dengan membaca kode sumber, karena beberapa dokumentasi perintah tidak ditulis dengan terlalu detail, sebaliknya dalam kode sumber akan ada penjelasan yang lebih rinci. Karena semua perintah ini ditulis dengan go, membacanya juga sangat mudah. Perintah-perintah ini semuanya berada di paket src/cmd, setiap sub-paket adalah perintah terpisah, entry point berada di file 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,
}
}Di sini Anda akan menemukan semua sub-perintah go, serta informasi dokumentasi bantuan mereka.
bug
$ go help bug
usage: go bug
Bug opens the default browser and starts a new bug report.
The report includes useful system information.Perintah ini tidak memiliki parameter atau flag apa pun, akan menggunakan browser default Anda untuk mengakses halaman issue repositori github.com/golang/go, memudahkan Anda untuk memberikan feedback bug, selain itu tidak ada fungsi lain.
version
Melalui perintah version dapat melihat informasi versi go saat ini.
$ go version -h
usage: go version [-m] [-v] [file ...]Tanpa parameter apa pun, akan menampilkan versi bahasa go saat ini
$ go version
go version go1.21.0 windows/amd64Juga menerima path file sebagai parameter, akan menampilkan versi go yang digunakan saat mengkompilasi semua file biner yang dapat diidentifikasi di path tersebut.
$ 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.0Parameter -v menentukan perintah version untuk mencoba menampilkan versi go dari file yang tidak dapat diidentifikasi, parameter -m menampilkan informasi modul file biner, serta beberapa parameter kompilasi, berikut adalah contoh sederhana.
$ 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 sendiri adalah file biner, sebenarnya tanpa parameter apa pun, go version menampilkan versi bahasa go dari file biner itu sendiri, karena semua toolchain cmd/go diimplementasikan oleh bahasa go itu sendiri.
env
Melalui perintah env dapat melihat semua informasi variabel lingkungan go, mengubah variabel lingkungan ini akan mempengaruhi perilaku toolchain go.
$ go env -h
usage: go env [-json] [-u] [-w] [var ...]
Run 'go help env' for details.Jalankan perintah ini tanpa parameter apa pun, akan menampilkan nilai semua variabel lingkungan go
$ go env
set GO111MODULE=on
set GOARCH=amd64
...Menambahkan nama variabel lingkungan tertentu sebagai parameter hanya dapat menampilkan nilai variabel tersebut
$ go env GO111MODULE
onMenambahkan -json dapat menampilkan format json
$ go env -json
{
"AR": "ar",
"CC": "gcc",
......
}Melalui flag -w, dan dengan parameter dalam bentuk var=value, akan mengubah nilai variabel tertentu secara permanen
$ go env -w GO111MODULE=onMenggunakan flag -u, dapat mengembalikan variabel tertentu ke nilai default
$ go env -u GO111MODULEJalankan go help environment untuk melihat pengenalan setiap variabel lingkungan
$ 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.
......Berikut adalah pengenalan beberapa variabel lingkungan yang umum digunakan
GOVERSION
Nilai variabel lingkungan ini tergantung pada versi bahasa go, dan nomor versi berasal dari file $GOROOT/VERSION, yang mencatat versi go saat ini dan waktu build.
$ cat $GOROOT/VERSION
go1.21.3
time 2023-10-09T17:04:35ZNilai variabel runtime.Version sama dengan nilai GOVERSION, dan variabel lingkungan ini tidak dapat dimodifikasi.
GOENV
Di direktori $GOROOT akan ada file konfigurasi default bernama 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=autoFormatnya sederhana yaitu key=value, nilai variabel lingkungan yang dimodifikasi melalui perintah go env -w key=value akan ditulis ke file konfigurasi. Namun juga dapat tidak menggunakan file konfigurasi default, variabel lingkungan GOENV dapat secara manual menentukan alamat file konfigurasi env, dan nilai variabel lingkungan GOENV hanya dapat ditimpa oleh variabel lingkungan sistem operasi, tidak dapat dimodifikasi oleh perintah go env -w.
GOHOSTARCH
Mewakili arsitektur CPU mesin ini, hanya untuk tampilan, nilai variabel lingkungan ini tidak dibaca dari file konfigurasi, dan tidak dapat dimodifikasi.
GOHOSTOS
Mewakili sistem operasi mesin ini, hanya untuk tampilan, nilai variabel lingkungan ini tidak dibaca dari file konfigurasi, dan tidak dapat dimodifikasi.
GOOS
Saat kompilasi, nilai GOOS akan menentukan sistem target mana kode sumber dikompilasi menjadi file biner, nilai default adalah GOHOSTOS, yaitu sistem operasi mesin ini, memiliki beberapa pilihan berikut
linuxdarwinwindowsnetbsdaixandroid
Sistem operasi yang didukung sebenarnya tidak hanya ini, gunakan perintah go tool dist list, lihat semua nilai yang didukung
$ 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
Saat kompilasi, nilai GOARCH akan menentukan arsitektur CPU mana yang digunakan saat kompilasi, nilai default adalah GOHOSTARCH, yaitu arsitektur CPU mesin ini, memiliki beberapa pilihan berikut
amd64386armppc64
Arsitektur yang didukung sebenarnya tidak hanya ini, gunakan perintah go tool dist list, lihat semua nilai yang didukung
$ go tool dist list | awk -F '/' '{print $2}' | awk '!seen[$0]++'
ppc64
386
amd64
arm
arm64
riscv64
wasm
loong64
mips
mips64
mips64le
mipsle
ppc64le
s390xPerlu dicatat bahwa GOOS dan GOARCH tidak dapat dikombinasikan secara sembarangan, beberapa sistem operasi hanya dapat mendukung arsitektur CPU tertentu.
GOROOT
GOROOT mewakili direktori root lokasi instalasi bahasa go, nilai GOROOT tidak dapat dimodifikasi secara langsung, dan hanya dapat ditimpa oleh variabel lingkungan sistem operasi.
$ ls $GOROOT -1
api
bin
codereview.cfg
CONTRIBUTING.md
doc
go.env
lib
LICENSE
misc
PATENTS
pkg
README.md
SECURITY.md
src
test
VERSIONDi direktori root terdapat beberapa folder atau file yang cukup penting
lib, menyimpan beberapa dependensi, saat ini hanya ada satu library yang berisi informasi zona waktu berbagai negara di dunia, berada di$GOROOT/lib/time, file biner yang dikompilasi tidak akan menyertakan informasi zona waktu ini.pkg, menyimpan beberapa library alat dan file header, misalnya perintahgo toolakan mencari file biner toolchain go di direktori$GOROOT/pkg/toolbin, menyimpan file biner, secara default hanya ada dua file eksekusigodangofmt,$GOROOT/binharus ditambahkan ke variabel sistem, jika tidak perintah go tidak dapat digunakan.src, menyimpan kode sumber goVERSION, file ini menyimpan informasi versi bahasa gogo.env, file ini adalah file konfigurasienvdefault
GOPATH
Nilai default GOPATH adalah $HOME/go, nilai variabel lingkungan ini menentukan ke mana harus pergi untuk mencari file yang diimpor saat mengurai pernyataan import. Di masa awal ketika tidak ada gomod, GOPATH khusus digunakan untuk menyimpan berbagai library pihak ketiga, strukturnya adalah sebagai berikut
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)Setelah gomod lahir, GOPATH hanya menjadi tempat untuk menyimpan dependensi yang diunduh oleh go get, serta untuk menyimpan file biner yang diunduh dan dikompilasi oleh go install. Perlu dicatat bahwa lokasi GOPATH tidak boleh sama dengan GOROOT, jika tidak tidak akan berfungsi.
$ go env GOBIN
warning: GOPATH set to GOROOT (/home/user/go) has no effectHingga saat penulis menulis artikel ini, versi bahasa go sudah mencapai go1.21.3, kecuali proyek yang sangat kuno, hampir tidak ada orang yang akan menggunakan gopath untuk mengelola dependensi lagi.
GOBIN
GOBIN digunakan untuk menyimpan file eksekusi biner pihak ketiga yang diunduh dan dikompilasi oleh go install, nilai defaultnya adalah $GOPATH/bin. Sama seperti $GOROOT/bin, direktori ini harus ditambahkan ke variabel lingkungan sistem operasi, jika tidak juga tidak dapat menggunakan file biner di direktori GOBIN.
GOMODCACHE
GOMODCACHE menunjukkan lokasi penyimpanan dependensi yang diunduh oleh go get, nilai defaultnya adalah $GOPATH/pkg/mod. Format penyimpanannya adalah sebagai berikut
$GOMODCACHE/domain/username/project@verionDi direktori tingkat yang sama akan ada folder bernama sumdb, digunakan untuk menyimpan informasi terkait database checksum dependensi.
GOCACHE
Menyimpan informasi cache yang digunakan untuk kompilasi, nilai defaultnya adalah $HOME/.cache/go-build, direktori ini akan menghasilkan file README.
$ 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.Setiap build akan menghasilkan banyak file, go akan meng-cache file-file ini untuk digunakan kembali saat kompilasi berikutnya.
GOTEMPDIR
Digunakan untuk file sementara yang dihasilkan saat kompilasi, misalnya file biner sementara yang akan dijalankan oleh go run. Nilai defaultnya adalah direktori sementara yang ditentukan oleh sistem operasi, di mac atau linux adalah /tmp, di windows adalah %TEMP%, juga dapat dimodifikasi ke lokasi yang ditentukan pengguna.
GO111MODULE
Variabel lingkungan ini menunjukkan cara mana yang digunakan untuk mengelola dependensi proyek go, memiliki tiga nilai yang tersedia
off, matikan gomod, gunakan gopath, dan abaikan semua filego.modon, gunakan gomod, jangan gunakan gopath (default).auto, deteksi otomatis, jika file proyek berisigo.modakan menggunakan gomod untuk manajemen
TIP
Mengapa disebut GO111MODULE, tidak langsung disebut GOMODULE, karena gomod pertama kali diluncurkan pada versi go1.11.
GOPROXY
Proxy modul go, nilai defaultnya adalah https://proxy.golang.org,direct, url dipisahkan dengan koma, direct berarti langsung menggunakan VCS untuk melewati proxy modul, hanya akan menjalankan yang后者 ketika yang pertama tidak dapat diakses, ada pilihan lain yang tersedia yaitu off, yang berarti melarang pengunduhan modul apa pun. Selain itu, GOPROXY juga dapat berupa alamat file, misalnya
GOPROXY=file://$(go env GOMODCACHE)/cache/downloadMelalui go get -x dapat melihat perintah yang dijalankan selama proses pengunduhan dependensi, dapat mengetahui apakah menggunakan proxy.
$ 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.1Menggunakan proxy modul dapat secara efektif meningkatkan kecepatan pengunduhan modul, pengguna di Tiongkok pada dasarnya tidak menggunakan proxy tidak akan dapat mengakses proxy default resmi, saat ini proxy modul pihak ketiga publik dan tepercaya adalah sebagai berikut
https://proxy.golang.com.cn, open source sekaligus menyediakan layanan versi enterprisehttps://goproxy.cn, disediakan dan open source oleh Qiniu Cloud
Tentu saja ada solusi proxy modul self-hosted open source: goproxy
GOSUMDB
GOSUMDB digunakan untuk mengatur alamat database deteksi checksum library dependensi, defaultnya adalah sum.golang.org, ketika Anda mengatur proxy, go akan mengakses database checksum melalui proxy.
GOPRIVATE
Variabel lingkungan GOPRIVATE digunakan untuk mengatur library privat, library yang cocok tidak akan divalidasi melalui sumdb, juga tidak akan melalui proxy, akan mengunduh dependensi langsung melalui VCS. Mendukung pengaturan wildcard, dipisahkan dengan koma, seperti yang ditunjukkan di bawah ini, semua dependensi dengan akhiran corp.example.com dan bernama github.com/gohper/myproject tidak akan melalui proxy dan sumdb.
GOPRIVATE=*.corp.example.com,github.com/gohper/myprojectJuga dapat langsung mengatur pengguna atau organisasi tertentu
GOPRIVATE=github.com/gopher,github.com/myorganizationGONOPROXY
Menunjukkan dependensi mana yang tidak perlu melalui proxy, aturannya sama dengan GOPRIVATE, dan akan menimpa GOPRIVATE.
GONOSUMDB
Menunjukkan dependensi mana yang tidak perlu melalui database checksum, aturannya sama dengan GOPRIVATE, dan akan menimpa GOPRIVATE.
GOINSECURE
Menunjukkan dependensi mana yang langsung diunduh menggunakan VCS, aturannya sama dengan GOPRIVATE, dan akan ditimpa oleh GONOPROXY dan GONOSUMDB.
GOVCS
Mengatur sistem kontrol versi manajemen modul, default public:git|hg,private:all. Juga dapat membatasi VCS domain tertentu, misalnya
GOVCS=github.com:git,evil.com:off,*:git|hgDalam batasan di atas, github hanya bisa menggunakan git, evil.com tidak diizinkan, menggunakan | dapat menunjukkan beberapa VCS. Jika tidak membuat batasan apa pun, dapat diatur seperti berikut
GOVCS=*:allJika tidak mengizinkan penggunaan VCS apa pun, dapat diatur seperti berikut
GOVCS=*:offGOWORK
Mengatur apakah workspace diaktifkan, default kosong yaitu diaktifkan, jika diatur ke off, maka tidak diaktifkan, akan mengabaikan semua file go.work.
GOTOOLDIR
Mengatur lokasi toolchain go yang akan digunakan, defaultnya adalah $GOROOT/pkg/tool, toolchain default juga disimpan di lokasi ini.
GODEBUG
Mengatur opsi debug, mengontrol beberapa perilaku eksekusi program go dalam bentuk key-value, misalnya
GODEBUG=http2client=0,http2server=0Pengaturan ini untuk memudahkan go kembali ke perilaku lama ketika ada perubahan yang tidak kompatibel selama pembaruan versi, misalnya di 1.21 tidak lagi mengizinkan situasi panic(nil) terjadi, untuk ini, go resmi secara khusus mencatat GODEBUG History, kunjungi GODEBUG untuk mempelajari lebih detail.
CGO_ENABLED
Menunjukkan apakah cgo diaktifkan, defaultnya 1, yaitu diaktifkan, diatur ke 0 maka dimatikan.
Variabel lingkungan di atas adalah yang umum digunakan, untuk beberapa yang tidak begitu umum tidak akan diperkenalkan terlalu banyak, seperti CGO, WASM, dll., jika tertarik dapat mempelajarinya sendiri.
build
Go mendukung dua jenis kompiler, gccgo dan gc. gcc adalah kompiler c/c++ lama yang mendukung berbagai bahasa termasuk go, yang后者 gc bukan berarti garbage collection, ini mengacu pada go compiler, bahasa go menyelesaikan bootstrap pada go1.5, gc adalah kompiler yang sepenuhnya ditulis dalam bahasa go, kode sumbernya berada di paket cmd/compile, karena sepenuhnya diimplementasikan dalam bahasa go, sangat mudah untuk memahami dan mempelajari mekanisme internalnya. Secara default, kompiler menggunakan gc untuk kompilasi. Ngomong-ngomong, debugger bahasa go juga terbagi dua, gdb dan dlv, yang pertama adalah debugger c/c++ lama yang mendukung berbagai bahasa termasuk go, yang后者 adalah debugger yang ditulis dalam bahasa go, dukungan untuk bahasa go lebih ramah, juga open source, direkomendasikan untuk menggunakan yang后者. Perintah build digunakan untuk mengkompilasi file sumber go menjadi file biner yang dapat dieksekusi, Anda akan mengalami pengalaman kompilasi yang sangat cepat, ini juga merupakan salah satu karakteristik bahasa go.
$ go build -h
usage: go build [-o output] [build flags] [packages]
Run 'go help build' for details.Menerima tiga parameter, satu adalah path output file yang ditunjukkan oleh flag -o, satu adalah flag build untuk mendefinisikan perilaku kompilasi build flags, yang terakhir adalah paket yang akan dikompilasi, parameter ini harus diletakkan di akhir. Berikut adalah contoh sederhana, tidak menggunakan flag build.
# Windows
$ go build -o .\bin\golearn.exe golearn
# macOS / Linux
$ go build -o ./bin/golearn golearn./bin/golearn.exe menunjukkan path output, golearn menunjukkan modul yang akan dikompilasi, juga dapat berupa file entry atau folder. Misalnya contoh sederhana di bawah ini adalah dengan main.go file entry sebagai target kompilasi.
# Windows
$ go build -o .\bin\golearn.exe main.go
# macOS / Linux
$ go build -o ./bin/golearn main.goSaat kompilasi akan mengabaikan semua file yang berakhiran _test.go, karena sesuai konvensi file-file tersebut adalah file testing.
Selain itu, perintah build juga mendukung banyak flag build untuk mengontrol beberapa perilaku saat kompilasi.
-x: Tampilkan instruksi detail selama proses kompilasi-n: Mirip dengan-x, tetapi perbedaannya hanya menampilkan instruksi tersebut, tetapi sebenarnya tidak mengeksekusinya.-v: Tampilkan paket yang dikompilasi-p: Jumlah konkurensi selama proses kompilasi-a: Paksa build ulang, meskipun sudah yang terbaru.-compiler: Tentukan kompiler mana yang digunakan,gccgoataugc, yang后者 adalah kompiler yang ditulis oleh go.-race: Aktifkan deteksi race condition-msan: Aktifkan analisis memori-asan: Aktifkan analisis alamat-cover: Aktifkan deteksi coverage kode-buildmode: Tentukan mode kompilasi, ada pilihanarchive,c-archive,c-shared,default,shared,exe,pie,plugin.-pgo, tentukan file pgo-trimpath: Hapus prefix path file sumber, misalnya path relatif/var/lib/go/src/main.go, setelah dihapus nama file yang diperoleh melaluiruntimesaat runtime hanya path relatif terhadap path modul/main.go, setelah mengaktifkan item ini, waktu kompilasi akan meningkat secara signifikan, sekitar 20-40%, tergantung pada jumlah file.-toolexec, beberapa perintah go yang dieksekusi sebelum kompilasi, formatnya adalah-toolexec 'cmd args'.-gcflags: Tentukan beberapa tag kompiler gc-gccgoflags: Tentukan beberapa tag kompiler gccgo-ldflags: Tentukan beberapa tag alat link
Untuk beberapa parameter passing seperti ldflags, dapat mengirim parameter seperti "-help" untuk mendapatkan nilai yang mungkin, misalnya
$ 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
......Di atas adalah yang umum digunakan, untuk yang lain yang tidak begitu umum dapat dipelajari sendiri.
gcflags
Melalui gcflags dapat mengirim beberapa parameter ke kompiler gc untuk mengontrol perilaku tertentu, format penggunaannya adalah -gcflags="pattern=args list", args list adalah daftar parameter, pattern adalah cakupan, ada beberapa nilai yang tersedia
main, path paket tingkat atas tempat file entry beradaall, modul saat ini dan semua dependensi dalam mode saat inistd, library standarcmd, berlaku untuk semua file sumber di paketcmd- Wildcard, seperti
.,./...,cmd/....
Aturan pattern ini berlaku untuk semua flag yang mendukung format ini, misalnya ldflags. Lihat nilai parameter yang tersedia melalui perintah berikut
$ go build -gcflags -help
用法:compile [选项] file.go...
-% 调试非静态初始化器
-+ 编译运行时
-B 禁用边界检查
-C 禁用错误消息中的列号打印
-D path
设置本地导入的相对路径
-E 调试符号导出
-I directory
添加目录到导入搜索路径
-K 调试缺失的行号
-L 对于受 //line 指令影响的错误位置,同时显示实际源文件名
-N 禁用优化
-S 打印汇编列表
-V 打印版本并退出
-W 类型检查后调试解析树
......Berikut adalah pengenalan beberapa parameter yang umum digunakan
-S: Tampilkan bentuk assembly kode-N: Matikan optimasi kompilasi-m: Tampilkan keputusan optimasi-l: Matikan inline fungsi-c: Jumlah konkurensi kompilasi-dwarf: Hasilkan tanda DWARF
Misalnya jika ingin melihat bentuk assembly kode, dapat menggunakan parameter -S, dan juga harus mematikan optimasi dan inline, baru dapat mengembalikan bentuk aslinya, seperti berikut
$ 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
Melalui ldflags dapat mengirim beberapa parameter ke linker untuk mengontrol perilaku tertentu, lihat semua nilai yang tersedia untuk ldflags melalui perintah berikut, hampir dua puluh tiga.
$ 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)
.....Parameter -X dari ldflags adalah fungsi yang sangat praktis, dapat mendefinisikan nilai variabel string paket yang ditentukan saat linking. Melalui fungsi ini, kita dapat dengan mudah menyuntikkan beberapa informasi meta saat kompilasi. Dan ini hanya variabel, jadi juga mudah untuk mendapatkannya saat runtime, berikut adalah contoh sederhana.
package main
import "fmt"
var (
Version string
)
func main() {
fmt.Println(Version)
}Jalankan perintah
go build -ldflags "-X main.Version=$(git describe --always)" main.goSetelah dijalankan akan menampilkan checksum sha1 commit git.
5e3fd7aBeberapa parameter lain yang cukup praktis adalah
-w: Tidak menghasilkan DWARF, ini adalah informasi yang memudahkan debug kode sumber.-s: Nonaktifkan tabel simbol
Kedua ini biasanya digunakan bersama, dapat secara signifikan mengurangi ukuran file biner setelah kompilasi, sekitar 40%-50%, kekurangannya juga jelas, tidak dapat melakukan debug, berikut adalah contoh.
$ go build -ldflags="-w -s" main.goKompilasi Silang
Kompilasi bahasa go selalu memiliki dua karakteristik besar, yang pertama adalah cepat, karakteristik besar lainnya adalah kompilasi silang, kompilasi silang berarti dapat mengkompilasi kode target sistem lain di lokal, misalnya di windows mengkompilasi menjadi file biner di linux atau darwin, sebaliknya juga sama. Bahasa yang mendukung kompilasi silang sangat banyak, ini bukan hal yang aneh, tetapi kompilasi silang bahasa go sangat sederhana, hanya perlu dua langkah berikut
- Atur variabel lingkungan GOOS, pilih sistem operasi target Anda
- Atur variabel lingkungan GOARCH, pilih arsitektur CPU target Anda
- Gunakan
go builduntuk kompilasi seperti biasa
Seluruh proses sangat singkat, tidak perlu menggunakan alat atau konfigurasi tambahan, dan kecepatannya sama cepatnya dengan biasanya. Seperti yang ditunjukkan di bawah ini
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_winLangkah pertama SET CGO_ENABLED=0 ini menonaktifkan cgo, sekali kode Anda menggunakan cgo, maka tidak dapat menggunakan kompilasi silang dengan normal. Langkah kedua SET GOOS mengatur sistem target, pilihan yang tersedia adalah linux, darwin, windwos, netbsd. Langkah ketiga mengatur arsitektur CPU, SET GOARCH, pilihan yang tersedia adalah amd64, 386, arm, ppc64. Langkah terakhir adalah melakukan kompilasi seperti biasa.
Kontrol Kompilasi
Perintah build dapat mencapai efek kontrol kompilasi melalui tags, ini ada dalam kode sumber dalam bentuk instruksi, lihat contoh, file product.go
// +build product
package main
import "fmt"
func main() {
fmt.Println("product")
}File debug.go
// +build debug
package main
import "fmt"
func main() {
fmt.Println("debug")
}Keduanya memiliki instruksi // +build, menunjukkan dalam situasi apa mereka akan dikompilasi. Format dasarnya adalah
// +build tag1 tag2
package pkg_nameAda beberapa aturan yang harus dipatuhi
//dan+buildharus dipisahkan satu spasi- Harus berada di atas deklarasi paket
- Harus dipisahkan satu baris kosong dengan deklarasi paket
Selain itu, juga dapat mencapai tujuan kontrol logika melalui interval sederhana, spasi menunjukkan OR, koma menunjukkan AND, ! menunjukkan NOT. Misalnya contoh di bawah ini
// +build windows linux
package pkg_nameMenunjukkan bahwa di platform windows atau linux file saat ini akan dikompilasi.
// +build windows,amd64,!cgo linux,i386,cgo
package pkg_nameContoh ini menunjukkan bahwa hanya akan dikompilasi di platform windows arsitektur amd64 dan tidak mengaktifkan cgo atau di platform linux arsitektur i386 dan mengaktifkan cgo. Jika Anda hanya tidak ingin membiarkan file tertentu tidak ikut dalam kompilasi, dapat menggunakan ignore.
// +build ignore
package pkg_nameJuga dapat ada instruksi multi-baris
// +build windows
// +build amd64
package pkg_nameInstruksi multi-baris ditangani dengan cara AND. Untuk tag platform dan arsitektur ini, saat kompilasi go akan mengirim secara otomatis, kita juga dapat mengirim tag kustom, ambil dua file paling awal sebagai contoh
$ go build -tags="debug" . && ./golearn.exe
debug
$ go build -tags="product" . && ./golearn.exe
productDapat melihat output berbeda saat mengirim tag berbeda, tujuan kontrol kompilasi juga tercapai.
run
Perintah run dan build keduanya akan mengkompilasi kode sumber, perbedaannya adalah perintah run akan langsung menjalankan setelah kompilasi selesai. Perintah run untuk mempercepat kecepatan kompilasi, tidak menghasilkan informasi debug selama proses kompilasi, jadi juga tidak mendukung debug, dan hanya menghasilkan file biner sementara, biasanya disimpan di direktori GOTMEPDIR, misalnya /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.Juga mendukung flag build perintah build, juga menyediakan parameter -exec untuk menunjukkan program mana yang akan menjalankan file biner, [arguments...] mengacu pada parameter running program. Berikut adalah contoh
package main
import (
"fmt"
"os"
)
var (
Version string
)
func main() {
fmt.Println(Version)
fmt.Println(os.Args[1:])
}Gunakan go run untuk menjalankan
$ go run -ldflags="-X main.Version=$(git describe --always)" main.go hello
5e3fd7a
[hello]Secara keseluruhan penggunaan tidak terlalu berbeda dengan go build, tidak akan dijelaskan terlalu banyak.
tool
Perintah tool sendiri tidak memiliki fungsi apa pun, fungsinya adalah langsung memanggil alat di direktori cmd/, misalnya cmd/compile adalah kompiler bawaan. Melalui go tool dapat langsung memanggil alat-alat ini, tidak perlu menjalankan file biner alat-alat ini secara manual.
$ go tool -h
usage: go tool [-n] command [args...]Gunakan parameter -n untuk mencetak semua parameter perintah yang didukung
$ go tool -n
addr2line
asm
buildid
cgo
compile
covdata
cover
doc
fix
link
nm
objdump
pack
pprof
test2json
trace
vetAlat-alat ini disimpan di direktori GOROOT/pkg/tool, dan dikelompokkan berdasarkan sistem operasi dan arsitektur CPU, seperti berikut.
$ 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*Gunakan format go doc cmd/command untuk melihat penggunaan setiap perintah, misalnya
$ 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.
...Parameter flag yang didukung oleh cmd/compile, juga merupakan parameter yang didukung oleh gcflags yang disebutkan sebelumnya. Perbedaan go tool compile dan go build adalah, yang pertama hanya bertanggung jawab untuk kompilasi, dan hanya dapat menggunakan file sebagai parameter, yang后者 dapat menggunakan folder, paket, file sebagai parameter, dan tidak hanya melakukan kompilasi kode sumber, juga bertanggung jawab untuk linking file, menghapus file yang tidak berguna, dll., yang pertama adalah bagian dari yang后者. Kita dapat mencetak perintah yang dieksekusi selama proses build
$ go build -n main.go
#
# internal/goarch
#
mkdir -p $WORK\b004\
cat >$WORK\b004\importcfg << 'EOF' # internal
# import config
EOF
"/golang/pkg/tool/windows_amd64/compile.exe" -o "$WORK/b004/_pkg_.a" -trimpath "$WORK/b004=>" -p internal/goarch -std -+ -complete -buildid 3gunEkUExGdhOPa2rFsh/3gunEkUExGdhOPa2rFsh -goversion go1.21.0 -c=4 -nolocalimports -importcfg "$WORK/b004/importcfg" -pack "/golang/src/internal/goarch/goarch.go" "/golang/src/internal/goarch/goarch_amd64.go" "/golang/src/internal/goarch/zgoarch_amd64.go"
"/golang/pkg/tool/windows_amd64/buildid.exe" -w "$WORK/b004/_pkg_.a" # internal
...Dalam proses dapat melihat ada bagian /golang/pkg/tool/windows_amd64/compile.exe ini,正是 memanggil kompiler. Selain compile, masih banyak alat yang dapat dipanggil, banyak perintah go sebenarnya adalah alias mereka.
clean
Perintah clean digunakan untuk menghapus file objek yang dihasilkan selama proses kompilasi
$ go clean -h
usage: go clean [clean flags] [build flags] [packages]
Run 'go help clean' for details.Mendukung flag berikut
-i: Hapus file arsip atau file biner yang sesuai-n: Cetak perintah yang akan dieksekusi selama proses pembersihan tetapi sebenarnya tidak mengeksekusi-x: Cetak perintah yang akan dieksekusi selama proses pembersihan dan eksekusi-r: Hapus secara rekursif melaluiimport path-cache, hapus semua cache yang dihasilkan olehgo build-testcache: Hapus semua cache testing yang dihasilkan-modcache: Hapus semua cache modul yang diunduh-fuzzcache: Hapus cache yang dihasilkan olehfuzz test.
Ketika menggunakan go tool compile, adalah langsung memanggil perintah kompiler, tidak seperti go build yang akan melakukan banyak penanganan afterwards, akan menghasilkan file objek. Misalnya jalankan perintah berikut
go tool compile -N -S -l main.goAkan menghasilkan file bernama main.o, gunakan perintah go clean untuk menghapus. Atau gunakan parameter -n untuk mencetak perintah yang akan dieksekusi.
$ 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.exeHapus cache kompilasi, ini akan menghapus cache kompilasi yang dihasilkan di direktori GOCACHE
$ go clean -cache -n
rm -r /cache/00 /cache/01 /cache/02Hapus cache yang dihasilkan oleh fuzz test, cache ini secara default disimpan di direktori GOCACHE/fuzz/
$ go clean -fuzzcache -n
rm -rf /cache/fuzzfix
Bahasa go hingga saat penulis menulis artikel ini sudah sepuluh tahun, selama proses pembaruan dan modifikasi bahasa yang terus-menerus, pasti akan muncul beberapa ketidakkompatibelan karena perubahan API, perintah fix lahir untuk ini, akan mendeteksi API yang sudah usang dalam file sumber dan menggantinya dengan API baru.
$ go fix -h
usage: go fix [-fix list] [packages]
Run 'go help fix' for details.Mendukung folder, nama file, direktori sebagai parameter, menerima flag -fix untuk mengirim parameter untuk menunjukkan modifikasi apa yang akan dilakukan, dapat melihat nilai yang tersedia melalui perintah got tool fix -help
$ 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.Berikut adalah contoh, kode sumber menggunakan paket golang.org/x/net/context
package main
import (
"fmt"
"golang.org/x/net/context"
)
func main() {
background := context.Background()
fmt.Println(background.Err())
}Gunakan go fix untuk memperbaiki, ganti dengan paket context di library standar, kita dapat menggunakan perintah berikut untuk mengganti
$ go fix -fix context main.goJuga dapat tidak mengganti, lihat perubahan file sebelum dan sesudah.
$ 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() {Bahasa go sudah lahir lebih dari sepuluh tahun hanya memiliki sembilan parameter pengganti yang tersedia, dapat dilihat kompatibilitas dijaga cukup baik.
fmt
fmt adalah alat pemformatan bawaan bahasa go, digunakan untuk memformat file kode sumber go.
$ go fmt -h
usage: go fmt [-n] [-x] [packages]
Run 'go help fmt' for details.Lihat dokumentasi detailnya melalui perintah go doc gofmt
$ 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 menggunakan tab untuk indentasi, spasi untuk alignment, secara default kode yang diformat akan ditampilkan di output standar, bukan menimpa file asli. Perintah go fmt sebenarnya menggunakan perintah gofmt, ini adalah file biner independen, berada di direktori GOROOT/bin.
$ ls $GOROOT/bin -1
go.exe*
gofmt.exe*Tambahkan flag -n ke perintah go fmt dapat mengetahui instruksi yang akan dieksekusi.
$ go fmt main.go
/golang/bin/gofmt.exe -l -w main.goDapat melihat go fmt sebenarnya adalah alias dari gofmt -l -w, perintah gofmt memiliki parameter berikut
-d: Tampilkan perbedaan file sebelum dan sesudah pemformatan-e: Tampilkan semua error-l: Tampilkan nama file yang berubah-r: Terapkan aturan pemformatan-s: Coba sederhanakan kode-w: Timpa file sumber, jika terjadi error kembalikan backup
Misalnya sekarang ada file sumber berikut
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("hello world!")}Melalui parameter -d dapat melihat preview perubahannya
$ 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!")
+}Parameter -l akan menampilkan nama file yang akan dimodifikasi
$ gofmt -l .
main.goJika ada error syntax, parameter -e dapat menampilkan lebih detail
$ 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 akan menerapkan modifikasi ke file sumber
$ gofmt -l -w .
main.go
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("hello world!")
}Anda dapat menemukan sebagai alat pemformatan, gofmt sama sekali tidak menyediakan konfigurasi kustom apa pun, sedangkan formatter prettify yang khusus untuk mempercantik kode js menyediakan banyak konfigurasi untuk memformat kode, di sini dapat mencerminkan sikap resmi go, jangan berpikir untuk melakukan personalisasi apa pun, kode semua orang sebaiknya konsisten, setidaknya ada satu keuntungan yaitu saat membaca kode tidak perlu beradaptasi dengan kebiasaan orang lain. Namun sebenarnya masih menyimpan satu item kustom, yaitu aturan pengganti kode yang diformat, aturan dapat dikustomisasi, formatnya adalah sebagai berikut
pattern -> replacementMisalnya menghapus kurung yang redundan
(a) -> aLihat perubahan file
$ 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!")
}Dapat melihat gofmt akan menghapus kurung yang redundan.
get
Perintah get pasti yang paling sering digunakan selama pengembangan go, fungsinya adalah mengunduh kode sumber paket alamat yang ditentukan ke direktori yang sesuai dengan GOMODCACHE.
$ go get -h
usage: go get [-t] [-u] [-v] [build flags] [packages]
Run 'go help get' for details.-u: Coba perbarui versi minor dan patch paket, jika melibatkan perubahan versi utama, sepertiv1->v2, tidak akan diperbarui.-t: Perbarui versi dependensi dalam testing-v: Tampilkan paket yang dikompilasi, sebenarnya merupakan salah satu parameterbuild flags
Di masa lalu, fungsi go get mirip dengan go install, akan mengunduh dan mengkompilasi paket-paket ini, namun dengan lahir dan penyempurnaan modul go, fungsi ini secara bertahap ditinggalkan, perintah get sekarang yang paling sering digunakan adalah untuk mengunduh dan mengurai dependensi untuk modul go, jadi Anda dapat melihat perintah go get juga mendukung flag build jenis ini, dan jika Anda mencoba menggunakan go get di luar modul seperti menggunakan go install, akan memberi tahu Anda bahwa penggunaan ini sudah dihapus.
$ 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'.Adapun mengapa masih mempertahankan ini dalam deskripsi dokumentasi juga tidak diketahui, melihat kode sumber perintah get, Anda masih akan menemukan flag-flag lama yang dipertahankan.
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
)Kembali ke topik utama, perintah get akan mengunduh kode sumber paket yang ditentukan ke direktori dependensi global lokal, yaitu direktori yang sesuai dengan GOCACHE, kemudian mencatat informasi ke file go.mod dan go.sum, yang pertama bertanggung jawab untuk mencatat versi, yang后者 bertanggung jawab untuk mencatat checksum sha1 untuk memastikan keamanan. Perintah get sebenarnya berbasis VCS, yaitu sistem kontrol versi lokal,总共 mendukung beberapa berikut
- git
- hg (Mercurial)
- bzr (Bazaar)
- svn
- fossil
Di antaranya, default hanya mendukung git dan hg, dapat dikonfigurasi di GOVCS, formatnya adalah sebagai berikut
GOVCS=github.com:git,example.com:hg,*:git|hg,*:allGOVCS hanya mendukung git dan hg sebagai VCS, tiga lainnya perlu dikonfigurasi di GOPRIVATE.
Perintah go get总共 memiliki beberapa cara penggunaan berikut, dapat langsung menggunakan alamat dependensi sebagai parameter
$ go get golang.org/x/netJuga dapat menentukan versi
$ go get golang.org/x/net@0.17.0Tentukan versi terbaru
$ go get golang.org/x/net@latestCoba perbarui versi
$ go get -u golang.org/x/netHapus dependensi tertentu
$ go get golang.org/x/net@noneDi atas ini digunakan untuk mengelola dependensi biasa, juga dapat digunakan untuk mengelola dependensi yang tidak begitu biasa, misalnya memperbarui versi bahasa go
$ go get go@latest
go: updating go.mod requires go >= 1.21.3; switching to go1.21.3
go: downloading go1.21.3 (windows/amd64)
go: upgraded go 1.21.0 => 1.21.3Bahkan juga dapat digunakan untuk memperbarui versi toolchain go
$ go get toolchain@latestKetika Anda menggunakan go get untuk memperbarui versi go dan toolchain, mereka akan menginstal versi go baru di direktori GOMODCACHE/golang.org/
$ ls $(go env GOMODCACHE)/golang.org -1
'toolchain@v0.0.1-go1.21.3.windows-amd64'/
x/Saat ini kemudian modifikasi GOROOT secara manual dapat beralih ke versi yang ditentukan.
install
Perintah install mirip dengan perintah get, keduanya digunakan untuk mengunduh dependensi pihak ketiga, tetapi perbedaannya adalah perintah get mengunduh kode sumber, sedangkan perintah install akan mengkompilasi kode sumber menjadi file biner yang dapat dieksekusi oleh mesin ini, path penyimpanan file biner pertama-tama di direktori GOBIN, kedua di GOPATH/bin. Fungsi utama perintah ini adalah untuk mengunduh beberapa alat command line publik pihak ketiga, berkat kecepatan kompilasi dan portabilitas bahasa go, tidak perlu mengunduh file biner, tetapi langsung mengunduh kode sumber kemudian mengkompilasi di lokal.
$ go install -h
usage: go install [build flags] [packages]
Run 'go help install' for details.Perintah install menerima flag build dan nama paket sebagai parameter, dalam kasus gomod diaktifkan, nama paket harus membawa nomor versi. Misalnya mengunduh debugger delve
$ go install -x github.com/go-delve/delve/cmd/dlv@latest
# get https://goproxy.cn/github.com/@v/list
# get https://goproxy.cn/github.com/go-delve/delve/cmd/@v/list
# get https://goproxy.cn/github.com/go-delve/delve/cmd/dlv/@v/list
# get https://goproxy.cn/github.com/go-delve/delve/@v/list
# get https://goproxy.cn/github.com/go-delve/@v/list
# get https://goproxy.cn/github.com/@v/list: 404 Not Found (0.014s)
# get https://goproxy.cn/github.com/go-delve/delve/cmd/@v/list: 404 Not Found (0.027s)
# get https://goproxy.cn/github.com/go-delve/delve/cmd/dlv/@v/list: 404 Not Found (0.027s)
# get https://goproxy.cn/github.com/go-delve/delve/@v/list: 200 OK (0.027s)
# get https://goproxy.cn/github.com/go-delve/@v/list: 404 Not Found (0.027s)
WORK=/home/user/tmp/go-build2033992495
mkdir -p $WORK/b001/
cat >/home/user/tmp/go-build2033992495/b001/importcfg.link << 'EOF' # internal
packagefile github.com/go-delve/delve/cmd/dlv=/home/user/.cache/go-build/f1/f11d552287458c0fce625abe50bf928c487064c36bbb1251ad8b1968772c3e4b-d
......
......
mkdir -p /home/wyh/gomod/bin/
mv $WORK/b001/exe/a.out /home/wyh/gomod/bin/dlv
rm -r $WORK/b001/Pertama-tama akan mengunduh kode sumber ke path yang disimpan di GOMODCACHE, ini sama dengan perintah get, kemudian beralih ke direktori kerja sementara, mengkompilasinya, setelah kompilasi selesai memindahkan file biner ke direktori GOPATH/bin, terakhir menghapus folder sementara. Perintah install juga memiliki batasan yaitu paket yang diunduh harus merupakan paket entry proyek tersebut, artinya harus berisi file entry main.go, jika tidak akan memberi tahu Anda tidak dapat menginstal. Misalnya, gunakan go install untuk mengunduh gin
$ go install -x github.com/gin-gonic/gin@latest
# get https://goproxy.cn/github.com/@v/list
# get https://goproxy.cn/github.com/gin-gonic/gin/@v/list
# get https://goproxy.cn/github.com/gin-gonic/@v/list
# get https://goproxy.cn/github.com/@v/list: 404 Not Found (0.022s)
# get https://goproxy.cn/github.com/gin-gonic/gin/@v/list: 200 OK (0.027s)
# get https://goproxy.cn/github.com/gin-gonic/@v/list: 404 Not Found (0.028s)
package github.com/gin-gonic/gin is not a main packagegin adalah library dependensi framework web, bukan alat command line, tentu saja tidak ada file entry, jadi juga akan gagal instalasi.
list
Perintah list akan menampilkan paket di lokasi yang ditentukan, satu baris per paket, dan mendukung output yang diformat kustom, mendukung banyak parameter, prasyarat penggunaannya adalah harus dalam proyek yang mendukung gomod.
$ go list -h
usage: go list [-f format] [-json] [-m] [list flags] [build flags] [packages]
Run 'go help list' for details.Parameter yang didukung adalah sebagai berikut
-f: Parameter pemformatan-json: Output format json-compiled: Tampilkan semua paket yang akan dikompilasi oleh kompiler-deps: Tampilkan nama setiap paket dan setiap paket yang dependensinya-test: Tampilkan paket testing setiap paket-e: Output normal saat bertemu paket error-find: Jangan uraikan hubungan dependensi paket-paket ini-export: Saat menggunakan parameter ini, atur nilai fieldPackage.Exportstruct ke file yang berisi informasi ekspor paket yang ditentukan terbaru, dan atur nilai fieldPackage.BuildIDkeBuildIDpaket, terutama untuk output yang diformat.
Parameter informasi modul,
-m: Tampilkan modul bukan output paket-versions: Tampilkan semua informasi yang tersedia untuk modul-retracted: Tampilkan versi yang ditarik dari modul
Parameter [packages] dapat berupa nama paket yang ditentukan, atau folder, juga dapat all, menunjukkan di mana saja, saat menggunakan parameter -m, all menunjukkan semua dependensi yang direferensikan oleh modul saat ini.
Misalnya, file saat ini hanya memiliki satu file main.go, dan hanya memiliki satu baris kode output "hello world", setelah menjalankan go list -deps ., menampilkan dari proyek saat ini ke fmt dan semua paket dependensi yang direferensikannya.
$ 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
golearnAtau output semua dependensi modul di bawah proyek saat ini
$ 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
Output perintah list adalah per baris, setiap baris output adalah satu paket. Resmi menyediakan parameter -f untuk kita mengustomisasi format output baris, nilai yang diterimanya adalah syntax template yang didefinisikan oleh paket engine template template/text, misalnya contoh berikut
-f "package {{ .Dir }} {{ .Name }}"Setiap paket yang diiterasi akan dimasukkan sebagai struct berikut, semua field dalam struct ini dapat digunakan sebagai parameter template.
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
}Jika mengiterasi modul, akan dimasukkan sebagai struct berikut, semua field-nya juga dapat digunakan sebagai parameter template.
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
}Lihat semua paket
$ 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 toolLihat modul
$ go list -m -f "mod {{.Path}} {{.Version}} {{.GoVersion}} {{.GoMod}}"
mod golearn 1.21.3 /golearn/go.modmod
go mod adalah perintah khusus untuk mengelola modul go.
$ go mod help
Go mod provides access to operations on modules.
Note that support for modules is built into all the go commands,
not just 'go mod'. For example, day-to-day adding, removing, upgrading,
and downgrading of dependencies should be done using 'go get'.
See 'go help modules' for an overview of module functionality.
Usage:
go mod <command> [arguments]
The commands are:
download download modules to local cache
edit edit go.mod from tools or scripts
graph print module requirement graph
init initialize new module in current directory
tidy add missing and remove unused modules
vendor make vendored copy of dependencies
verify verify dependencies have expected content
why explain why packages or modules are needed
Use "go help mod <command>" for more information about a command.Memiliki beberapa sub-perintah berikut
download: Unduh semua dependensi yang tercantum dalam filego.modke cache lokaledit: Edit filego.mod, antarmuka baris perintah yang disediakannya terutama disediakan untuk dipanggil oleh alat atau skrip lain.init: Inisialisasi proyek gomod di direktori saat initidy: Unduh dependensi yang hilang, hapus dependensi yang tidak digunakangraph: Output grafik dependensiverify: Verifikasi dependensi lokalwhy: Jelaskan mengapa bergantung pada modul-modul inivendor: Ekspor dependensi proyek ke direktori vendor
init
$ go help mod init
usage: go mod init [module-path]Perintah init digunakan untuk menginisialisasi proyek gomod, satu-satunya parameter adalah path modul, di masa depan jika orang lain ingin mengunduh dependensi Anda perlu menggunakan path modul ini sebagai dasar. Aturan penamaannya umumnya adalah
domain_name/user_name/repo_nameMisalnya umumnya semua orang akan menempatkan proyek di github, jadi dapat
github.com/jack/gotourTidak terlalu direkomendasikan menggunakan simbol khusus sebagai path modul. Lihat contoh penggunaan
$ 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]Perintah tidy akan menghapus item dependensi yang tidak berguna di go.mod, yaitu item dependensi yang tidak direferensikan, serta akan mengunduh item dependensi yang direferensikan tetapi tidak ada. Mendukung parameter berikut
-v, output modul dependensi yang dihapus-e, abaikan error jika terjadi selama proses dan lanjutkan eksekusi-x, output proses eksekusi-go=version, perbarui versi go di filego.mod-compact=version, pertahankan checksum tambahan apa pun yang diperlukan dari versi Go utama yang ditentukan untuk berhasil memuat grafik modul, dan jika perintahgoversi ini memuat paket yang diimpor apa pun dari versi modul yang berbeda, akan menyebabkan tidy error. Parameter ini umumnya jarang digunakan, umumnya hanya akan error saat perubahan versi, dapat pergi ke stackoverflow lihat jawaban ini go modules - go mod tidy error message: "but go 1.16 would select" - Stack Overflow
Lihat contoh penggunaan
$ 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]Meskipun nama perintah download diterjemahkan sebagai unduh, tetapi hanya mengunduh dependensi ke cache dependensi lokal, tidak akan memodifikasi file go.mod, fungsinya adalah pre-download dependensi ke cache file lokal, jika ingin mengunduh dependensi tertentu, direkomendasikan menggunakan go get atau go mod tidy.
Berikut adalah beberapa contoh penggunaan
$ 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)Jika tanpa parameter apa pun, akan mengunduh semua dependensi yang ada di file go.mod tetapi tidak ada di cache dependensi lokal, jika tidak ada yang perlu diunduh akan output
go: no module dependencies to downloadedit
$ go help mod edit
usage: go mod edit [editing flags] [-fmt|-print|-json] [go.mod]edit adalah antarmuka baris perintah, digunakan untuk memodifikasi file go.mod, umumnya disediakan untuk program lain digunakan, beberapa editor IDE untuk menyediakan dukungan gomod akan menggunakan perintah-perintah ini. Mendukung parameter berikut
-module, ubah path modul-go=version, ubah versi go yang diharapkan-require=path@version, tambahkan item dependensi-droprequire=path@version, hapus item dependensi-exclude=path@version, tambahkan item dependensi yang dikecualikan-dropexclude=path@version, hapus item dependensi yang dikecualikan-replace=old@version=new@version, tambahkan item dependensi pengganti-dropreplace=old@version, hapus item dependensi pengganti-retract=version, tambahkan item rollback versi-dropretract=version, hapus item rollback versi
Beberapa parameter lain untuk tampilan
-print, output konten file-json, output dalam format json
Misalnya contoh di bawah ini
$ 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]Perintah graph akan output grafik dependensi di bawah proyek saat ini, readability-nya sangat buruk, dan sebagian besar waktu bukan untuk dibaca manusia, hasilnya biasanya akan diproses kemudian ditampilkan dalam bentuk visual. Setiap baris adalah satu dependensi, formatnya adalah sebagai berikut
引用方 被引用方Misalnya
golearn go@1.21.3Juga mendukung dua parameter
-go=version, gunakan versi go yang diberikan untuk memuat grafik dependensi, nilainya tidak boleh kurang dari versi di filego.mod.-x, tampilkan perintah yang dieksekusi selama proses.
Lihat contoh penggunaan sederhana
$ 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 adalah solusi alternatif gopath sebelum gomod diluncurkan, setiap proyek go akan memiliki direktori vendor, menyimpan dependensi setiap proyek secara terpisah sesuai dengan format domain/user/project, seperti node_module yang gemuk di sebelah NodeJs setiap proyek dependensi disimpan terpisah, cara manajemen dependensi ini sekarang terlihat memang sangat bodoh, tetapi pada saat itu memang tidak ada solusi yang lebih baik, alasan mempertahankan vendor adalah karena go menganut janji kompatibilitas ke bawah, beberapa proyek lama termasuk kode sumber go mungkin masih menggunakan vendor.
Kembali ke topik utama, vendor adalah sub-perintah go mod, dapat mengekspor dependensi global yang direferensikan oleh modul saat ini ke direktori vendor.
$ go mod vendor -h
usage: go mod vendor [-e] [-v] [-o outdir]
Run 'go help mod vendor' for details.Memiliki beberapa parameter berikut
-o: Tentukan path folder output-v: Output setiap dependensi-e: Jangan keluar saat terjadi error tetap lanjutkan
Lihat contoh di bawah ini, pertama gunakan go list -m all untuk melihat dependensi yang direferensikan oleh proyek saat ini
$ 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.1Ekspor ke direktori vendor saat ini
$ 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.v3Struktur direktori setelah ekspor adalah sebagai berikut
└─vendor
├─github.com
│ ├─davecgh
│ │ └─go-spew
│ │ └─spew
│ ├─pkg
│ │ └─errors
│ ├─pmezard
│ │ └─go-difflib
│ │ └─difflib
│ └─stretchr
│ └─testify
│ └─assert
└─gopkg.in
| └─yaml.v3
|
|--modules.txtDi antaranya modules.txt adalah file yang mendeskripsikan semua item dependensi, mirip dengan go.mod saat ini.
verify
$ go help mod verify
usage: go mod verifyPerintah ini akan memeriksa apakah dependensi proyek telah dimodifikasi sejak diunduh ke lokal. Misalnya, jika tidak ada masalah akan output all modules verified
$ go mod verify
all modules verifiedJika tidak akan melaporkan di mana terjadi perubahan, dan mengakhiri perintah dengan status tidak normal. Misalnya
$ 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...Jelaskan mengapa paket ini bergantung, sebenarnya adalah output grafik dependensi terkait. Misalnya
$ go mod why gorm.io/gorm
# gorm.io/gorm
golearn
gorm.io/gormSecara default hanya akan mengurai impor dari main, tambahkan parameter -m dapat menganalisis situasi impor setiap paket.
work
Perintah work adalah alat pengembangan lokal untuk manajemen multi-modul go
$ go work help
Work provides access to operations on workspaces.
Note that support for workspaces is built into many other commands, not
just 'go work'.
The commands are:
edit edit go.work from tools or scripts
init initialize workspace file
sync sync workspace build list to modules
use add modules to workspace file
vendor make vendored copy of dependencies
Use "go help work <command>" for more information about a command.init
Sub-perintah init digunakan untuk menginisialisasi workspace, perintah ini akan membuat file bernama go.work
$ go work init -h
usage: go work init [moddirs]
Run 'go help work init' for details.Terima parameter [moddirs] untuk menentukan modul mana yang akan dimasukkan ke dalam manajemen, misalnya
$ go work init ./service ./apiuse
Sub-perintah use digunakan untuk menambahkan direktori modul yang dikelola ke 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.Terima [moddirs] sebagai parameter, ada -r yang menunjukkan pencarian rekursif modul di path [moddirs], misalnya
$ go work use -r ./oss-api ./multi_modulesedit
Fungsi sub-perintah edit sama dengan go mod edit, keduanya disediakan untuk antarmuka baris perintah untuk alat dan skrip lain beroperasi.
$ 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 adalah sebagai berikut
-fmt, format filego.work-use,-dropuse, tambahkan dan hapus path modul-replace=old[@v]=new[@v],-dropreplace=old[@v]=new[@v], digunakan untuk menambahkan dan menghapus modul yang akan diganti-go,-toolchain=name, tentukan versi go, dan tentukan toolchain yang akan digunakan-print, cetak modifikasi terakhir, tidak tulis kembali ke file-json, output dalam formatjson, tidak dapat digunakan bersama dengan-print, struktur tipe yang sesuai adalah sebagai berikutgotype 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 }
Beberapa contoh penggunaan adalah sebagai berikut, output format
$ go work edit -fmt -print
go 1.22.0
use (
./ab/cd
./auth
./user
)Output json
$ go work edit -fmt -json
{
"Go": "1.22.0",
"Use": [
{
"DiskPath": "./ab/cd"
},
{
"DiskPath": "./auth"
},
{
"DiskPath": "./user"
}
],
"Replace": null
}sync
Sub-perintah sync digunakan untuk mengembalikan daftar modul di go.work ke masing-masing modul di workspace.
$ go help work sync
usage: go work sync
Sync syncs the workspace's build list back to the
workspace's modulesProses ini terutama terjadi setelah pengembangan lokal selesai, setiap modul telah menyelesaikan pekerjaan rilis, saat ini menggunakan sync, akan memperbarui dependensi di go.mod semua modul worksapce berdasarkan hubungan dependensi masing-masing modul, sehingga tidak perlu kita memperbarui secara manual.
vendor
Perintah vendor akan membuat salinan semua library dependensi modul di workspace ke direktori vendor.
$ go work help vendor
usage: go work vendor [-e] [-v] [-o outdir]Fungsi sama dengan go mod vendor, tidak akan dijelaskan terlalu banyak.
vet
Perintah vet adalah alat pemeriksaan error statis kode sumber bahasa go, seperti alat lint bahasa lain, misalnya 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.Pertama lihat contoh sederhana, sekarang ada kode sumber berikut
$ cat main.go
package main
import "fmt"
func main(){
fmt.Println("hello world!"
}Jalankan go vet tanpa parameter apa pun di direktori tingkat yang sama
$ go vet
vet: ./main.go:6:28: missing ',' before newline in argument list (and 1 more errors)vet akan melaporkan file mana baris mana出了什么问题。Mendukung flag build sebagai parameter, misalnya -n dan -x, mendukung paket, folder, nama file sebagai parameter.
$ go vet .
$ go vet main.go
$ go vet ./cmd
$ go vet runtimeLihat parameter dan penjelasan lebih detail melalui perintah berikut.
$ 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
......Perintah go tool vet tidak dapat langsung digunakan untuk memeriksa kode, harus menggunakan go vet. [vet flag] di parameter go vet mendukung pengaturan analyzer kode, nilai yang tersedia adalah sebagai berikut
asmdecl Periksa apakah file assembly cocok dengan deklarasi go
assign Periksa apakah ada variabel yang tidak berguna
atomic Periksa apakah merusak atomisitas saat menggunakan sync/atomic
bools Periksa apakah salah menggunakan operator logika
buildtag Periksa build tag
cgocall Periksa perilaku yang melanggar aturan passing pointer cgao
composites Periksa复合结构 yang tidak diinisialisasi, seperti map, chan
copylocks Periksa apakah terjadi penyalinan nilai lock
directive Periksa perintah toolchain go
errorsas Periksa apakah mengirim tipe non-pointer atau non-error ke errors.As
framepointer Periksa apakah assembly yang dioptimalkan kompilasi menghapus frame pointer sebelum menyimpannya
httpresponse Periksa apakah salah menggunakan httpresponse
ifaceassert Periksa type assertion dari interface ke interface
loopclosure Masalah referensi variabel loop
lostcancel context.WithCancel tidak menggunakan fungsi cancel
nilfunc Periksa apakah ada perbandingan yang tidak berguna antara fungsi dan nil
printf Periksa apakah parameter pemformatan printf benar
shift Periksa apakah ada shift yang sama dengan atau melebihi lebar integer
sigchanyzer Periksa chan os.Signal yang tidak buffered
slog Periksa panggilan log terstruktur yang tidak sah
stdmethods Periksa apakah signature metode interface yang diketahui benar
stringintconv Periksa konversi string integer
structtag Periksa apakah tag struct benar
testinggoroutine Periksa apakah menggunakan goroutine untuk memanggil testing.Fatal dalam testing
tests Periksa penggunaan umum error dalam testing dan contoh
timeformat Periksa apakah format waktu yang digunakan oleh (time.Time).Format atau time.Parse benar
unmarshal Periksa apakah mengirim tipe non-pointer atau non-interface ke unmarshal
unreachable Periksa kode yang tidak dapat dijangkau
unsafeptr Periksa konversi uintptr ke unsafe.Pointer yang tidak benar
unusedresult Periksa nilai return fungsi yang tidak digunakanSemua ini adalah analyzer yang menganalisis titik tertentu, misalnya analyzer timeformat memeriksa apakah panggilan time.Format sesuai dengan syntax yang benar. Secara default semua analyzer di atas akan diaktifkan, aktifkan secara terpisah dapat menggunakan format berikut
$ go vet -timeformat main.goNonaktifkan secara terpisah
$ go vet -timeformat=false main.goKode sumber analyzer ini berada di cmd/vendor/golang.org/x/tools/go/analysis/passes, setiap analyzer adalah satu perangkap yang mudah dilakukan oleh bahasa go, jadi sangat direkomendasikan menggunakan perintah vet untuk memeriksa kode Anda. Selain ini, juga mendukung beberapa flag parameter lain
-V, hanya cetak versi lalu keluar-json, output dalam format json-c=n, tampilkan jumlah baris konflik dalam konteks (sepertinya tidak ada efek apa pun)
Juga ada beberapa analyzer eksternal, misalnya shadows, bertanggung jawab untuk mendeteksi masalah variable hiding dari penamaan variabel pendek, karena eksternal jadi perlu menggunakan go install untuk mengunduh
$ go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latestFormat penggunaan adalah sebagai berikut
$ 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.Perintah test adalah perintah yang menyediakan fungsi testing dalam toolchain bahasa go, fungsi ini cukup penting, untuk sebuah software而言, testing yang lengkap adalah hal yang sangat diperlukan. Di sini hanya简单介绍 bagaimana menggunakan perintah test, jika ingin mempelajari lebih banyak tentang testing, kunjungi: Testing
Selain mendukung parameter kompilasi perintah build, test juga mendukung beberapa parameter berikut
-args, parameter entry program-c, kompilasi file biner testing paket saat ini ke direktori saat ini tetapi tidak mengeksekusi, beri nama dengan carapkg.test-exec, jalankan beberapa perintah lain sebelum testing dimulai-json, gaya output testing menjadi json-o, tentukan path name file biner testing
Juga mendukung banyak testflag, gunakan perintah help untuk melihat semua testflag
$ go help testflag
`go test` 命令既接受作用于 `go test` 本身的标志,
也接受作用于生成的测试二进制文件的标志。
`go test` 命令识别以下标志,并用于控制任何测试的执行:
-bench regexp
-benchtime t
-count n
......Perkenalkan beberapa yang umum digunakan
-v, output hasil testing setiap use case.-timeout duration, waktu timeout eksekusi testing-skip regexp, lewati use case testing yang ditentukan-short, persingkat waktu running untuk use case testing yang memakan waktu lama-shuffle, acak urutan eksekusi semua use case testing-run regexp, jalankan use case testing yang ditentukan-list regexp, daftar setiap use case testing-cpu 1,2,4, tentukan jumlah cpu-count n, tentukan berapa kali setiap use case testing dieksekusi
Penggunaan paling sederhana adalah, tanpa parameter apa pun, akan mengeksekusi semua use case testing di bawah paket saat ini, dan output hasilnya.
$ ls *_test.go
hello_test.go
$ go test
PASS
ok golearn 0.522sTentukan file testing tertentu
$ go test hello_test.go
ok command-line-arguments 0.041sTambahkan parameter -v dapat melihat output yang lebih detail, ini cukup sering digunakan.
$ go test -v hello_test.go
=== RUN TestHello
hello_test.go:6: hello world!
--- PASS: TestHello (0.00s)
PASS
ok command-line-arguments 0.041sTentukan use case testing tertentu
$ go test -v -run TestHello
=== RUN TestHello
hello_test.go:6: hello world!
--- PASS: TestHello (0.00s)
PASS
ok golearn 0.028sSaat testing, perintah test memiliki dua mode, pertama-tama bahas mode folder, ketika menjalankan perintah test tanpa parameter package, akan menjalankan testing dengan mode folder, misalnya beberapa perintah di bawah ini
$ go test
$ go test -vDalam mode ini, nonaktifkan cache testing. Mode lainnya adalah mode list, ketika parameter package tidak kosong, akan menjalankan testing dengan mode list, perbedaannya dengan yang前者 adalah apakah mengaktifkan cache testing. Misalnya beberapa di bawah ini
$ go test -v .
$ go test -v ./...
$ go test .
$ go test -v net/httpDalam mode list, go akan mengkompilasi setiap file testing di bawah paket yang ditentukan menjadi file biner dan mengeksekusinya, untuk menghindari running testing berulang, go secara default akan meng-cache hasilnya, tidak akan mengkompilasi ulang saat running kedua kali. Gunakan parameter berikut akan secara default mengaktifkan cache
-benchtime-cpu-list-parallel-runshort-timeout-failfast-v
Gunakan parameter lain selain parameter ini dapat menonaktifkan cache, metode yang direkomendasikan resmi adalah menggunakan -count=1 untuk menonaktifkan cache. Misalnya
$ go test -v -count=1 ./...Instruksi
Berbeda dengan perintah, instruksi go ada dalam file sumber dalam bentuk hard-coded, mereka memiliki nama lain yang lebih terminologis: compiler directives (pragma directives).
Compiler dan linker akan mengubah perilaku mereka sendiri karena mereka sehingga mencapai efek kontrol kompilasi, sedikit mirip dengan macro dalam bahasa c, tentu saja tidak semua instruksi digunakan untuk mempengaruhi kompilasi, sebagian digunakan untuk perilaku fungsional lain, misalnya instruksi generate umumnya digunakan untuk fungsi pembuatan kode. Instruksi ini umumnya ada dalam bentuk komentar, dan menggunakan //go: sebagai prefix, di antaranya tidak boleh berisi spasi apa pun, misalnya instruksi //go:generate. Semua jenis instruksi总共 dibagi menjadi dua
- Instruksi fungsional, ini adalah instruksi fungsional yang disediakan oleh go dapat digunakan secara bebas, seperti
generate,embed,build. - Instruksi compiler, jenis instruksi ini perlu digunakan dengan hati-hati, penggunaan sembarangan dapat menyebabkan hasil yang tidak dapat diprediksi.
Selain instruksi fungsional, sebagian besar instruksi hanya dapat bertindak pada signature fungsi. Untuk instruksi compiler dapat menjalankan perintah go doc compile untuk melihat instruksinya. Untuk semua instruksi, dapat menemukan informasi terkait mereka di cmd/compile/internal/ir/node.go: 440.
generate
$ go help generate
usage: go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]Instruksi generate sesuai namanya adalah terkait pembuatan, umumnya fungsinya adalah untuk menjalankan perintah yang akan menghasilkan kode dan memperbarui kode sumber, tetapi sebenarnya dapat menjalankan perintah apa pun. Dan, instruksi generate berbeda dengan instruksi lain, memiliki perintah khusus yang dapat digunakan untuk menjalankan semua instruksi generate yang berada di file sumber. Dapat menggunakan nama file atau nama paket sebagai parameter input untuk menunjukkan file mana yang akan menjalankan instruksi generate, berikut adalah parameter lainnya.
-run=regex, jalankan instruksi generate yang ditentukan-skip=regex, lewati instruksi generate yang ditentukan-n, cetak perintah yang akan dieksekusi-x, cetak perintah yang dieksekusi selama proses-v, output file yang diproses
Selain itu, perintah yang dieksekusi dalam instruksi generate juga mendukung beberapa parameter built-in berikut
$GOARCH, arsitektur cpu$GOOS, sistem operasi$GOFILE, nama file$GOLINE, nomor baris$GOPACKAGE, nama paket$GOROOT, go root$DOLLAR, simbol dolar$PATH, variabel lingkungan path
Lihat contoh, tidak ada kode apa pun hanya satu baris komentar
package main
//go:generate echo "hello world!"Jalankan perintah
$ go generate .
hello world!Contoh ini adalah menjalankan perintah go
package main
//go:generate go versionJalankan perintah
$ go generate .
go version go1.21.3 windows/amd64Instruksi generate dapat digunakan untuk menjalankan perintah apa pun, misalnya swagger menghasilkan dokumentasi API, atau Wire menghasilkan kode IOC. Namun instruksi ini tidak cocok untuk menjalankan perintah yang terlalu kompleks, cocok untuk menjalankan perintah singkat, jika ada kebutuhan kompleks dapat menggunakan skrip atau makefile sebagai pengganti.
embed
Instruksi embed adalah baru di 1.16, fungsinya adalah dapat mengemas file statis bersama ke dalam file biner, misalnya template HTML之类的。Formatnya adalah sebagai berikut
//go:embed patternpattern dapat berupa ekspresi glob, juga dapat berupa folder atau file tertentu. Lihat contoh
package main
import "embed"
//go:embed *
var static embed.FSInstruksi embed mengharuskan berada di atas variabel global dengan tipe embed.Fs, perhatikan harus variabel global, dan menggunakannya harus mengimpor paket embed, dalam contoh ini, * mewakili akan mengemas semua file di bawah folder saat ini ke dalam file biner, tetapi tidak akan mengizinkan folder yang dimulai dengan ..
Contoh di bawah ini menunjukkan membaca konten dari file yang disematkan
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))
}Hanya memiliki tiga metode, penggunaannya tidak berbeda dengan sistem file biasa, dan karena mengimplementasikan antarmuka io/Fs, juga dapat diteruskan sebagai objek Fs.
func (f FS) Open(name string) (fs.File, error)
func (f FS) ReadFile(name string) ([]byte, error)
func (f FS) ReadDir(name string) ([]fs.DirEntry, error)Contoh di bawah ini menunjukkan menyematkan file html melalui instruksi embed, dan mengakses melalui layanan http.
package main
import (
"embed"
"net/http"
)
//go:embed index.html
var htmlFs embed.FS
func main() {
http.Handle("/", http.FileServer(http.FS(htmlFs)))
http.ListenAndServe(":8080", http.DefaultServeMux)
}Hasil akses adalah sebagai berikut
$ 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>Instruksi embed juga mendukung tipe variabel global dapat berupa []byte, misalnya contoh di bawah ini
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)
}Efek yang diimplementasikan tidak jauh berbeda dengan contoh sebelumnya.
$ 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
Di bagian build-Kontrol Kompilasi, dibahas menggunakan instruksi // +build untuk mengontrol perilaku kompilasi. Sedangkan instruksi //go:build adalah baru di 1.17, dimaksudkan untuk menggantikan instruksi sebelumnya, tetapi sekarang sudah 1.21 juga belum menggantikan, diperkirakan akan ada dalam bentuk koeksistensi di masa depan, tentang instruksi baru ini, dokumentasi resmi juga memiliki pengenalan: build constraints. Fungsinya tidak berbeda dengan yang前者, tetapi syntax lebih ketat, mendukung ekspresi boolean, lihat contoh
//go:build (linux && 386) || (darwin && !cgo)
package pkg_nameCara ini readability jauh lebih tinggi daripada yang asli.
line
Instruksi line akan mempengaruhi nomor baris, nomor kolom, dan nama file baris berikutnya, fungsinya hanya ini, sebagian besar waktu mungkin digunakan untuk debug error之类的。Misalnya saat terjadi error, akan mengubah informasi output compiler.
package main
var a undefinedType
func main() {
}Secara normal, compiler akan output
.\main.go:3:7: undefined: undefinedTypeTetapi jika menggunakan instruksi line, akan berbeda
package main
//line abc.go:10:100
var a undefinedType
func main() {
}Maka outputnya adalah
abc.go:10:106: undefined: undefinedTypeDan karena alasan warisan sejarah, instruksi line juga merupakan satu-satunya instruksi yang penggunaannya berbeda dengan instruksi lain. Formatnya adalah
//line filename:line:columnDapat melihat tidak memerlukan go: sebagai prefix.
linkname
Operasi instruksi ini dapat digunakan untuk linking fungsi atau variabel global paket lain, bahkan jika itu adalah tipe privat, operasi ini sering muncul di library standar terutama runtime, beberapa fungsi tidak memiliki body fungsi diimplementasikan melalui cara ini, bagian lain dari fungsi body kosong diimplementasikan oleh assembly. Lihat penggunaannya, format penggunaan adalah sebagai berikut
//go:linkname nama_tipe_link tipe_yang_di-linkDan sebelum menggunakannya, misalnya mengimpor paket unsafe. Lihat contoh sederhana linking tipe privat di library standar
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")))
}Output
15395306441938000233Ini menghubungkan fungsi privat runtime.memhash dengan fungsi yang kami deklarasikan sendiri, fungsi ini tidak memiliki body fungsi hanya signature, hanya berfungsi sebagai carrier. Fungsi memhash adalah给定 pointer, seed hash, dan offset memori, menghitung hash berdasarkan memori. Proses linking ini selesai selama kompilasi,
Jika bukan library standar, maka situasinya agak berbeda, misalnya di paket example ada fungsi test, sebelum linking pertama-tama harus mengimpor paket ini secara anonim.
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())
}Output
aDapat melihat sudah berhasil linking, metode ini dapat melewati sistem modul go untuk melakukan apa saja, tetapi tidak direkomendasikan untuk digunakan secara besar-besaran, kecuali Anda tahu apa yang Anda lakukan.
noinline
Instruksi noinline menunjukkan satu fungsi dilarang optimasi inline, bahkan jika sangat sederhana. Lihat contoh sederhana
package main
func val() string {
return "val"
}
func main() {
var c = val()
_ = c
}val adalah fungsi yang sangat sederhana, fungsinya adalah mengembalikan literal string, karena terlalu sederhana dan hasilnya selalu dapat diprediksi, maka saat kompilasi akan dioptimalkan oleh compiler menjadi bentuk berikut
package main
func main() {
var c = "val"
_ = c
}Lihat seperti apa assembly-nya, dapat melihat tidak ditemukan panggilan fungsi val.
TEXT main.val(SB), NOSPLIT|NOFRAME|ABIInternal, $0-0
FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
LEAQ go:string."val"(SB), AX
MOVL $3, BX
FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
RETSelanjutnya tambahkan instruksi noinline
package main
//go:noinline
func val() string {
return "val"
}
func main() {
var c = val()
_ = c
}Lihat lagi bentuk assembly-nya
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
RETKali ini dapat melihat dengan sangat jelas panggilan main.val ini, dan ini正是 fungsi yang dimainkan oleh instruksi noinline, mencegah inline fungsi saat optimasi compiler.
nosplit
Instruksi nosplit berfungsi untuk melewati deteksi overflow stack. Karena model penjadwalan konkurensi go adalah penjadwalan preemptive, asumsikan satu fungsi akan menjalankan kode yang sangat low-level, goroutine lain saat memanggil fungsi ini tidak cocok untuk di-preempt, dapat menggunakan instruksi ini untuk menunjukkan.
//go:nosplit
func nospilitFn()Setelah menggunakan instruksi ini, juga tidak akan ada pertumbuhan stack lagi.
noescape
noescape, dari namanya dapat dengan mudah menebak terkait escape, fungsinya adalah menunjukkan fungsi saat ini tidak akan terjadi perilaku memory escape, setelah eksekusi selesai semua sumber daya akan di-recycle, dan fungsi ini harus hanya memiliki signature tanpa body fungsi, dalam kasus ini umumnya implementasi fungsi diimplementasikan oleh assembly.
Misalnya memhash yang digunakan sebelumnya akan menggunakan instruksi ini
//go:noescape
//go:linkname memhash runtime.memhash
func memhash(p unsafe.Pointer, h, s uintptr) uintptrDengan begini, compiler tidak akan melakukan analisis escape terhadapnya, prasyaratnya adalah Anda harus memastikan tidak akan terjadi escape, jika terjadi, maka tidak tahu apa konsekuensinya.
uintptrescapes
Instruksi uintptrescapes menunjukkan parameter tipe uinptr dalam fungsi ini dikonversi menjadi nilai pointer dan escape ke heap, dan harus tetap hidup. Instruksi ini umumnya digunakan untuk beberapa sistem call low-level, sebagian besar情况下 tidak perlu memahaminya.
//go:uintptrescapes
func nospilit(ptr uintptr) uintptrDi masa lalu seharusnya ada instruksi notinheaps yang digunakan untuk menunjukkan satu tipe tidak diizinkan mengalokasikan memori ke heap, tidak tahu di versi mana dihapus.
norace
Instruksi norace menunjukkan akses memori satu fungsi tidak lagi memerlukan analisis race condition, umumnya digunakan saat menjalankan kode low-level tidak cocok untuk melakukan analisis race condition.
//go:norace
func low_level_code(ptr uintptr) uintptrTIP
Sebagian instruksi dibatasi hanya dapat digunakan oleh paket runtime, eksternal tidak dapat menggunakannya, mereka akan melibatkan hal yang lebih dalam, ingin memahami dapat melihat pengenalan terkait mereka di Runtime-only compiler directives.
