本文更新於2021-03-30。
翻譯自Command go官方文檔(https://golang.org/cmd/go/,國內可使用https://golang.google.cn/cmd/go/;同理,文中golang.org的鏈接也可使用golang.google.cn替換)。章節段落結構稍作改變,對應的go版本為1.16。
- go
- go bug——啟動bug報告
- go build——編譯包及其依賴包
- go clean——刪除對象文件和緩存文件
- go doc——查看包或符號的文檔
- go env——打印環境變量
- go fix——使用新的API更新包代碼
- go fmt——gofmt(重新格式化)包代碼
- go generate——通過執行源代碼生成Go文件
- go get——添加依賴包至當前模塊並安裝之
- go help——查看幫助信息
- go install——編譯並安裝模塊及其依賴
- go list——列出包和模塊
- go mod——模塊維護
- go run——編譯並運行Go程序
- go test——測試包
- go tool——運行指定的go tool
- go version——打印Go版本
- go vet——報告包中有可能的錯誤
- buildconstraint主題——構建約束
- buildmode主題——構建模式
- c主題——Go和C之間的調用
- cache主題——構建和測試緩存
- environment主題——環境變量
- filetype主題——文件類型
- go.mod主題——go.mod文件
- gopath主題——GOPATH環境變量
- gopath-get主題——遺留的GOPATH的go get
- goproxy主題——模塊代理協議
- importpath主題——import路徑語法
- module-auth主題——使用go.sum的模塊校驗
- module-get主題——模塊感知的go get
- modules主題——模塊,模塊版本,及更多
- packages主題——包列表和模式
- private主題——下載非公共代碼的配置
- testflag主題——測試標志
- testfunc主題——測試函數
- vcs主題——用GOVCS控制版本控制
go
go <command> [arguments]
go是管理Go源代碼的工具。
command可參閱 go help——查看幫助信息 小節。
go bug——啟動bug報告
go bug
打開默認瀏覽器並啟動新的bug報告,報告包括有用的系統信息。
go build——編譯包及其依賴包
go build [-o output] [build flags] [packages]
編譯指定導入路徑的包,以及其依賴包,但不安裝結果。
如果構建的參數為單個目錄下的.go文件列表時,會將它們當作指定單個包的源文件列表。
當編譯包時,忽略以“_test.go”結尾的文件。
當編譯單個main包時,生成的可執行文件會被寫入到以第一個源文件(如:“go build ed.go rx.go”寫入“ed”或“ed.exe”)或源代碼目錄名(如:“go build unix/sam”寫入“sam”或“sam.exe”)命名的輸出文件中。當寫入Windows下的可執行文件時會添加“.exe”后綴。
當編譯多個包或單個非main包時,build編譯包但會丟棄目標對象文件,行為只用於類似檢查包是否可以構建。
標志(flag):
- -i:同時安裝目標的依賴包。-i標志被反對使用。編譯的包會自動被緩存。
- -o output:強制將結果可執行文件或對象文件寫入指定名字的輸出文件或目錄,而不是在本節最上兩個段落所描述的默認行為。如果指定的名字為一個已存在的目錄或者以斜杠或反斜杠結尾,則所有結果可執行文件將寫入到該目錄中。
構建標志(build flags)會被build、clean、get、install、list、run、test命令共享:
- -a:強制重新構建已經是最新的包。
- -asmflags '[pattern=]arg list':傳遞給每次go tool asm調用的參數。
- -buildmode mode:使用的構建模式,更多信息參閱“go help buildmode”。
- -compiler name:使用的編譯器名,即runtime.Complier(gccgo或gc)。
- -gccgoflags '[pattern=]arg list':傳遞給每次gccgo編譯器/鏈接器調用的參數。
- -gcflags '[pattern=]arg list':傳遞給每次go tool complie調用的參數。
- -installsuffix suffix:在包安裝目錄名字中使用的后綴,以便使輸出文件與默認構建分開。如使用-race標志,安裝后綴會自動設置為race,或如果顯式設置則在其后追加_race。對-msan也同樣。使用需要使用非默認編譯標志的-buildmode選項也又類似效果。
- -ldflags '[pattern=]arg list':傳遞給每次go tool link調用的參數。
- -linkshared:鏈接到的之前使用-buildmode=shared生成的共享庫。
- -mod mode:使用的模塊下載模式:readonly、vendor或mod。默認情況下,如果vendor目錄存在且go.mod中的go版本為1.14或更高,go命令表現如同-mod=vendor被設置一樣。否則,go命令表現如同-mod=readonly被設置一樣。詳情參閱https://golang.org/ref/mod#build-commands。
- -modcacherw:令保留在模塊緩存中的新創建的目錄可讀寫,而不是令它們只讀。
- -modfile file:在模塊感知模式下,讀取(並且可能寫入)備用的go.mod文件而不是在模塊根目錄下的go.mod文件。名字為“go.mod”的文件仍然必須存在用來確定模塊根目錄,但其不會被訪問。當-modfile被指定,備用的go.sum文件也會被使用:其路徑從-modfile標志產生,通過去除“.mod”擴展名並追加“.sum”。
- -overlay file:讀取為構建操作提供覆蓋的JSON配置文件。文件是只有一個字段的JSON結構,名為“Replace”,映射每個磁盤文件路徑(一個字符串)至其后備文件路徑,以使構建運行起來如同磁盤文件路徑存在有后備文件路徑提供的內容,或如果其后備文件路徑為空則如同磁盤文件路徑不存在。對-overlay標志的支持有一些限制:重要的是,從包含路徑之外包含的cgo文件必需與Go包被包含於相同的目錄,且當二進制和測試分別通過go run和go test運行時覆蓋不會出現。
- -msan:啟用與內存清理程序的互操作,只支持linux/amd64、linux/arm64,並且只能使用clang/llvm作為宿主C編譯器。在linux/arm64上,pie構建模式將被使用。
- -n:打印實際需執行的命令,但不運行。
- -p n:可以並行運行的程序——如構建命令或測試二進制文件——的數量。默認為可用的CPU的數量。
- -pkgdir dir:從dir而不是通常的位置安裝和加載所有包(pkg)。例如,當使用非標准設置構建時,使用-pkgdir來令在特定的目錄生成包。
- -race:啟用數據競態檢測,只支持linux/amd64、freebsd/amd64、darwin/amd64、windows/amd64、linux/ppc64le、linux/arm64(只對48位VMA)。
- -tags tag,list:構建期間需滿足的構建標記(tag),為逗號分隔的列表。關於構建標記,參閱go/build包文檔中關於構建約束的描述。(早期Go版本使用空白分隔的列表,已經被反對使用,但仍然能識別。)
- -toolexec 'cmd args':用來調用如如vet和asm等工具鏈程序的程序。例如,使用go命令運行“cmd args /path/to/asm
”,而不是運行asm。 - -trimpath:從目標可執行文件中移除所有文件系統路徑。作為文件系統絕對路徑的替代,記錄下的文件名將以“go”(對標准庫),或“模塊路徑@版本”(當使用模塊),或“import路徑”(當使用GOPATH)開頭。
- -v:打印編譯的包名。
- -work:打印臨時工作目錄並在退出時不刪除之。
- -x:打印實際需執行的命令,並運行。
-asmflags、-gccgoflags、-gcflags、-ldflags接受一個以空白分隔的參數列表,用以在構建時傳遞給底層工具。要在列表元素中嵌入空白,需使用單引號或雙引號括起。參數列表前面可以是一個包模式和一個等號,它將該參數列表的使用限制為與該模式匹配的包(有關包模式的說明,請參閱“go help packages”)。如果沒有模式,參數列表只應用於命令行中命名的包。這些標志可以使用不同的模式重復指定,以便為不同的包指定不同的參數。如果一個包與多個標志中給定的模式匹配,則使用最后一個指定的。例如:“go build -gcflags=-S fmt”只打印fmt包的反匯編,“go build -gcflags=all=-S fmt”則打印fmt包及其所有依賴包的反匯編。
有關指定包的詳細信息,參閱“go help packages”。有關包和二進制文件的安裝位置的詳細信息,參閱“go help gopath”。有關Go和C/C++之間調用的詳細信息,參閱“go help c”。
注意:構建遵守某些約定,例如在“go help gopath”中描述的。然而,並不是所有項目都能遵守這些約定。使用自己的約定來安裝,或使用一個單獨的軟件構建系統,可以選擇使用低級別的調用,如“go tool compile”和“go tool link”,來避免構建工具的開銷和設計決策。
參閱:go install,go get,go clean。
go clean——刪除對象文件和緩存文件
go clean [clean flags] [build flags] [packages]
從包源代碼目錄中刪除對象文件。go命令在臨時目錄中構建大多數對象文件,因此go clean主要關心通過其他工具或通過手動調用go build遺留下來的對象文件。
如果給出packages參數或者-i或-r標志,clean將從與導入路徑對應的每個源文件目錄中刪除以下文件:
- _obj/:舊的對象文件目錄,來自Makefile。
- _test/:舊的測試文件目錄,來自Makefile。
- _testmain.go:舊的gotest文件,來自Makefile。
- test.out:舊的測試日志,來自Makefile。
- build.out:舊的測試日志,來自Makefile。
- *.[568ao]:對象文件,來自Makefile。
- DIR(.exe):來自go build。
- DIR.test(.exe):來自go test -c。
- MAINFILE(.exe):來自go build MAINFILE.go。
- *.so:來自SWIG。
在上述列表中,DIR表示目錄路徑的最后一個元素,MAINFILE表示目錄中任何在構建包時未包含的go源文件的基本名。
標志:
- -cache:刪除整個go build緩存。
- -i:刪除相關的已安裝的歸檔文件或二進制文件(由“go install”創建)。
- -modcache:刪除整個模塊下載緩存,包括指定版本依賴的已解壓的源代碼。
- -n:打印實際需執行的命令,但不運行。
- -r:遞歸地應用於所有由導入路徑指定的依賴包。
- -testcache:令go build緩存中所有測試結果過期。
- -x:打印實際需執行的命令,並運行。
關於構建標志的更多信息,參閱“go help build”。
關於指定包的更多信息,參閱“go help packages”。
go doc——查看包或符號的文檔
go doc [-u] [-c] [package|[package.]symbol[.methodOrField]]
打印由參數(包、常量、函數、類型、變量、方法、結構體字段)指定的項相關的文檔注釋,該項后跟該項下的每個第一級項(該項為包即為包級聲明,該項為類型即為其方法,依次類推)的一行概要。
doc命令接受0個、1個或2個參數。
如使用0個參數,即運行:
go doc
會打印當前目錄下包的包文檔。如果包是命令的包(main包),包的導出符號會從展示輸出中省略,除非指定了-cmd標志。
當使用1個參數運行時,參數會被視為要展示文檔的項的Go語法表示。參數指定的項取決於GOROOT和GOPATH中安裝的內容,以及參數的格式。參數的格式如下所示:
go doc <pkg>
go doc <sym>[.<methodOrField>]
go doc [<pkg>.]<sym>[.<methodOrField>]
go doc [<pkg>.][<sym>.]<methodOrField>
上述列表中參數匹配的第一項是待打印文檔的項。(參見下面的示例。)但是,如果參數是以大寫字母開頭的,則假設其表示當前目錄中的符號或方法。
對於包,掃描順序是從詞匯上按廣度優先確定的。也就是說,呈現的包是匹配搜索的其中一個,並且為最接近搜索根,在其層次結構中搜索到的從詞匯上來說的第一個。GOROOT樹總是在GOPATH之前被完整掃描。
如果沒有包被指定或被匹配,則選擇當前目錄下的包,因此“go doc Foo”顯示當前目錄中符號為Foo的文檔。
包路徑必須是限定路徑或者是路徑的正確后綴。go工具通常的包機制不適用於:類似“.”和“...”的包路徑元素,是不被go doc實現的。
當使用2個參數運行時,第一個參數必須是完整的包路徑(而不僅僅是后綴),第二個參數是一個符號、符號的方法或符號的結構體字段。這與godoc接受的語法類似:
go doc <pkg> <sym>[.<methodOrField>]
在所有的形式中,當匹配符號時,參數的小寫字母不區分大小寫,但大寫字母只匹配大寫。這意味着如果不同的符號有不同的大小寫,則包中小寫字母參數可能有多個匹配。如果這種情況發生,將打印所有匹配項的文檔。
示例:
- go doc:顯示當前包的文檔。
- go doc Foo:顯示當前包中Foo的文檔。(Foo以大寫字母開頭,因此其不能匹配為一個包路徑。)
- go doc encoding/json:顯示encoding/json包的文檔。
- go doc json:encoding/json的簡寫。
- go doc json.Number(或go doc json.number):顯示json.Number的文檔和方法概要。
- go doc json.Number.Int64(或go doc json.number.int64):顯示json.Number的Int64方法的文檔。
- go doc cmd/doc:顯示doc命令的包文檔。
- go doc -cmd cmd/doc:顯示doc命令的包文檔和導出符號。
- go doc template.new:顯示html/template的New函數的文檔。(html/template從詞匯上來說位於text/template之前。)
- go doc text/template.new(一個參數):顯示text/template的New函數的文檔。
- go doc text/template new(兩個參數):顯示text/template的New函數的文檔。
至少在當前的包樹結構中,以下調用均會打印json.Decoder的Decode方法的文檔:
- go doc json.Decoder.Decode
- go doc json.decoder.decode
- go doc json.decode
- cd go/src/encoding/json; go doc decode
標志:
- -all:顯示包的所有文檔。
- -c:匹配符號時區分大小寫。
- -cmd:將命令(main包)當作普通包看待。否則當顯示包的頂層文檔時,main包的導出符號將被隱藏。
- -short:每個符號一行表示。
- -src:顯示符號的完整源代碼。這將顯示其聲明和定義的完整Go代碼,如函數定義(包括函數體),類型聲明或閉包引用的常量塊。輸出可能因此包含未導出的細節。
- -u:像導出符號、方法、字段一樣顯示未導出的符號、方法、字段的文檔。
go env——打印環境變量
go env [-json] [-u] [-w] [var ...]
打印Go環境變量信息。
env默認像shell腳本(在Windows下,像批處理文件)一樣打印信息。如果一個或多個變量名作為參數給定,env將為每個指定名字的變量新起一行打印其值。
標志:
- -json:以JSON格式打印環境變量,而不是像shell腳本一樣。
- -u:需要一個或多個參數,如果指定名字的環境變量已經使用“go env -w”設置,則取消其默認設置。
- -w:需要一個或多個格式為NAME=VALUE的參數,使用指定的值修改指定名字的環境變量的默認設置。
關於環境變量的更多信息,參閱“go help environment”。
go fix——使用新的API更新包代碼
go fix [packages]
在通過導入路徑指定的包上運行Go fix命令。
關於fix的更多信息,參閱“go doc cmd/fix”。關於指定包的更多信息,參閱“go help packages”。
如需使用特定的選項,運行“go tool fix”。
參閱:go fmt,go vet。
go fmt——gofmt(重新格式化)包代碼
go fmt [-n] [-x] [packages]
在導入路徑指定的包上運行“gofmt -l -w”命令。將打印被修改的文件名。
關於gofmt的更多信息,參閱“go doc cmd/gofmt”。關於指定包的更多信息,參閱“go help packages”。
標志:
- -mod:標志的值設置要使用那種模塊下載模式:readonly還是vendor。更多信息參閱“go help modules”。
- -n:打印實際需執行的命令,但不運行。
- -x:打印實際需執行的命令,並運行。
如需使用特定的選項,直接運行gofmt。
參閱:go fix,go vet。
go generate——通過執行源代碼生成Go文件
go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]
通過在現存文件中描述的指令執行命令。命令可以運行任何進程,但目的是創建或更新Go源文件。
go generate永遠不會通過go build、go get、go test等自動運行。必須明確地運行。
go generate掃描文件搜索指令,指令是如下格式的行:
//go:generate command argument...
(注意:開頭沒有空白,“//go”中間也沒有空白)其中command是要運行的生成器,對應於可在本地運行的可執行文件。其必須在shell PATH中(如gofmt),或為一個完全限定路徑(如/usr/you/bin/mytool),或為一個命令別名,如下所述。
注意go generate不解析文件,因此在注釋或多行字符串中看起來像指令的行將會被視為指令。
指令的參數是空白分隔的記號,記號可為雙引號引起的字符串,在生成器運行時每個記號作為獨立的參數傳遞給生成器。
帶引號的字符串使用Go語法,並在執行前進行計算;一個帶引號的字符串作為生成器的一個單獨的參數。
為了向人類和機器工具傳達,代碼是自動生成的,生成的源代碼應有一行匹配如下的正則表達式(以Go語法):
^// Code generated .* DO NOT EDIT\.$
該行必需出現在文件中第一行非注釋、非空行文本之前。
go generate在運行生成器時會設置幾個環境變量:
- $GOARCH:執行時的體系結構(arm、amd64等)。
- $GOOS:執行時的操作系統(linux、windows等)。
- $GOFILE:文件的基本名(base name)。
- $GOLINE:指令在源文件中的行號。
- $GOPACKAGE:包含指令的文件的包名。
- $DOLLAR:一個美元符號。
除了變量替換和帶引號的字符串求值,在命令行上不會執行諸如“globbing”(文件名通配符匹配)之類的特殊處理。
作為執行命令前的最后一步,對任何以字母數字命名的環境變量(如$GOFILE或$HOME)的任何調用,均會在命令行中展開。在所有的操作系統上環境變量名的展開語法都類似$NAME這樣。由於求值的順序,環境變量甚至在帶引號的字符串中也會展開。如果名字為NAME的環境變量未設置,$NAME會展開為空字符串。
如下形式的指令:
//go:generate -command xxx args...
表示,只對於此源文件的接續部分,字符串xxx代表由參數指定的命令。這可以用來創建別名或處理多個單詞的生成器。例如:
//go:generate -command foo go tool foo
表示,命令“foo”代表生成器“go tool foo”。
generate按照命令行中給定的順序處理包,一次一個。如果命令行列出一個單獨的目錄中的.go文件,它們會作為一個單獨的包對待。在包中,generate按照包中文件名的順序處理源文件,一次一個。在一個源文件中,generate按照在文件中出現的順序運行生成器,一次一個。go generate工具還會設置構建標記“generate”,以便文件可以被go generate審查但會在構建時忽略。
對於帶有無效代碼的包,generate只處理帶有有效包子句的源文件。(譯注:未看懂)
如果任何一個生成器返回了錯誤退出狀態,“go generate”會跳過該包所有接續的處理。
生成器運行在包的源代碼目錄中。
標志:
- -run="":如果非空,指定一個正則表達式來選擇執行的指令,該指令的完整原始源文本(忽略結尾處的空白和換行)匹配正則表達式。
也接受標准的構建標志,包括-v、-n和-x。
- -n:打印實際需執行的命令,但不運行。
- -v:打印正在處理的包名和文件名。
- -x:打印實際需執行的命令,並運行。
關於構建標志的更多信息,參閱“go help build”。
關於指定包的更多信息,參閱“go help packages”。
go get——添加依賴包至當前模塊並安裝之
go get [-d] [-t] [-u] [-v] [-insecure] [build flags] [packages]
get解析其命令行參數為特定模塊版本的包,更新go.mod來依賴於那些版本,下載源代碼至模塊緩存,然后構建和安裝指定名字的包。
要添加對包的依賴或更新其至最后的版本:
go get example.com/pkg
要更新或下載包至特定的版本:
go get example.com/pkg@v1.2.3
要移除對模塊的依賴並降級依賴於它的模塊:
go get example.com/mod@none
詳情參閱https://golang.org/ref/mod#go-get。
“go install”命令可以用來構建和安裝包。當版本被指定時,“go install”運行在模塊感知模式並忽略當前目錄中的go.mod文件。例如:
go install example.com/pkg@v1.2.3
go install example.com/pkg@latest
詳情參閱“go help install”或https://golang.org/ref/mod#go-install。
除了構建標志(在“go help build”中列出),“go get”接受以下的標志:
- -d:不構建和安裝包。get將只更新go.mod並下載構建包所需的源代碼。
- -insecure:允許使用諸如HTTP等不安全的方案,從倉庫拉取以及解析自定義域名,並且也會繞過使用校驗和數據庫的模塊校驗和檢驗。謹慎使用。此標志已被反對使用並將在go的未來版本中移除。要允許使用不安全的方案,改用GOINSECURE環境變量。要繞過模塊校驗和檢驗,使用GOPRIVATE或GONOSUMDB。詳情參閱“go help environment”。
- -t:同時添加命令行中指定的包構建測試所需的模塊。
- -u:同時更新命令行中指定的包的依賴模塊,令依賴模塊使用較新的次版本的發布版本或補丁版本的發布版本,前提是這些版本可用。
- -u=patch:(不是-u patch)同樣更新依賴模塊,但不同之處在於默認選擇補丁版本的發布版本。
當-t和-u一起使用時,將也會更新構建測試所需的模塊的依賴模塊。
使用get來構建和安裝包被反對使用。在將來的發布版本中,-d標志會默認啟用,且“go get”將只用來調整當前模塊的依賴。要從當前模塊通過依賴來安裝包,使用“go install”。要忽略當前模塊來安裝包,在每個參數后面帶有如“@latest”的@version后綴來使用“go install”。
關於模塊的更多信息,參閱https://golang.org/ref/mod。
關於指定包的更多信息,參閱“go help packages”。
上文介紹了get使用模塊來管理源代碼和依賴的行為。如果相反,go命令運行在GOPATH模式下,get的標志和行為的細節也會改變,如同“go help get”的內容也會不同。參閱“go help gopath-get”。
參閱:go build、go install、go clean、go mod。
go help——查看幫助信息
go help
go help <command>
go help <topic>
命令(command)為:
- bug:啟動bug報告。
- build:編譯包及其依賴包。
- clean:刪除對象文件和緩存文件。
- doc:查看包或符號的文檔。
- env:打印環境變量。
- fix:使用新的API更新包代碼。
- fmt:gofmt(重新格式化)包代碼。
- generate:通過執行源代碼生成Go文件。
- get:添加依賴包至當前模塊並安裝之。
- help:查看幫助信息。
- install:編譯並安裝模塊及其依賴。
- list:列出包和模塊。
- mod:模塊維護。
- run:編譯並運行Go程序。
- test:測試包。
- tool:運行指定的go tool。
- version:打印Go版本。
- vet:報告包中有可能的錯誤。
關於命令的更多信息,參閱“go help <command>”。
額外的幫助主題(topic)為:
- buildconstraint:構建約束。
- buildmode:構建模式。
- c:Go和C之間的調用。
- cache:構建和測試緩存。
- environment:環境變量。
- filetype:文件類型。
- go.mod:go.mod文件。
- gopath:GOPATH環境變量。
- gopath-get:遺留的GOPATH的go get。
- goproxy:模塊代理協議。
- importpath:import路徑語法。
- module-auth:使用go.sum的模塊校驗。
- module-get:模塊感知的go get。
- modules:模塊,模塊版本,及更多。
- packages:包列表和模式。
- private:下載非公共代碼的配置。
- testflag:測試標志。
- testfunc:測試函數。
- vcs:用GOVCS控制版本控制。
關於主題的更多信息,參閱“go help <topic>”。
go install——編譯並安裝模塊及其依賴
go install [build flags] [packages]
編譯並安裝導入路徑指定的包。
可執行文件安裝在GOBIN環境變量指定的目錄中,默認為$GOPATH/bin或如果GOPATH環境變量沒有設置時為$HOME/go/bin。$GOROOT中的可執行文件安裝在$GOROOT/bin或$GOTOOLDIR,而不是$GOBIN。
如果參數有版本后綴(如@latest或@v1.0.0),“go install”在模塊感知模式下構建包,忽略當前目錄或任何父目錄中的go.mod文件,如果有的話。這對安裝可執行文件而不影響主模塊的依賴很有用。為了消除關於構建中要使用哪個模塊版本的歧義,參數必需滿足以下約束:
- 參數必需為包路徑或包模式(帶有“...”通配符)。不能是標准包(如fmt),元模式(std、cmd、all),相對或絕對文件路徑。
- 所有的參數帶有相同的版本后綴。不同的查詢是不允許的,即使它們指向相同的版本。
- 所有的參數必需指向相同模塊相同版本中的包。
- 不能有模塊被認作“main”模塊。如果包含命令行中指定名字的包的模塊有go.mod文件,其不能包含可能導致其被不一樣地解析為主模塊的指令(replace和exclude)。模塊不能依賴於自身的一個更高的版本。
- 包路徑參數必需指向main包。模式參數只會匹配main包。
如果參數沒有版本后綴,“go install”可能運行在模塊感知模式或GOPATH模式,取決於GO111MODULE環境變量和go.mod文件的存在。詳情參閱“go help modules”。如果模塊感知模式啟用,“go install”運行在主模塊的上下文中。
當模塊感知模式禁用,其它包被安裝在目錄$GOPATH/pkg/$GOOS_$GOARCH中。當模塊感知模式啟用,其它包被構建和緩存但不會被安裝。
標志:
- -i:同時安裝指定名字的包的依賴。-i標志被反對使用。已編譯的包會被自動緩存。
關於構建標志的更多信息,參閱“go help build”。關於指定包的更多信息,參閱“go help packages”。
參閱:go build、go get、go clean。
go list——列出包和模塊
go list [-f format] [-json] [-m] [list flags] [build flags] [packages]
列出指定名字的包,一行一個。最常用的標志是-f和-json,用以控制每個包的輸出打印格式。其他標志,文檔於下文,控制更多特定的細節。
默認輸出顯示包的導入路徑:
bytes
encoding/json
github.com/gorilla/mux
golang.org/x/net/html
標志(-f或-m外的其他標志的說明需參閱-f或-m):
-
-complied:將CompiledGoFiles設置為提交給編譯器的Go源文件。通常,這意味着其會重復GoFiles列出的文件,然后也會添加通過處理CgoFiles和SwigFiles生成的Go代碼。Imports列表包含來自GoFiles和CompiledGoFiles所有導入的並集。
-
-deps:不只是遍歷指定名字的包,也會遍歷它們的依賴。list以深度優先后序遍歷的方式遍歷它們,因此一個包會在它的所有依賴之后列出。未在命令行中顯式列出的包將有一個設置為true的DepOnly字段。
-
-e:改變對錯誤包的處理方式,那些錯誤包或者不存在或者內容殘缺。默認情況下,list命令為每個錯誤包打印一條錯誤信息至標准錯誤輸出中,然后在普通的打印中忽略這些錯誤包。使用-e標志,list命令將不會打印錯誤信息至標准錯誤輸出中,而是以普通打印的方式處理錯誤包。錯誤包將有非空的ImportPath和非nil的Error字段;其他信息可能會也可能不會缺失(置為零值)。
-
-export:將Export字段設置為包含指定包最新導出信息的文件名。
-
-f:指定list使用的替換格式,使用template包的語法。默認的輸出等同於-f '{{.ImportPath}}'。傳遞給模板的結構體為:
type Package struct { Dir string // 包含包源代碼的目錄 ImportPath string // 目錄中包的導入路徑 ImportComment string // 包說明中導入注釋的路徑 Name string // 包名 Doc string // 包文檔字符串 Target string // 安裝路徑 Shlib string // 包含本包的共享庫(只在設置-linkshared時使用) Goroot bool // 本包是否在GOROOT中 Standard bool // 本包是否是Go標准庫之一 Stale bool // “go install”會否為本包進行一些處理 StaleReason string // 當Stale==true時的解析原因 Root string // 包含本包的GOROOT或GOPATH目錄 ConflictDir string // 本目錄在$GOPATH中的同名目錄 BinaryOnly bool // 是否僅為二進制包(不再支持) ForTest string // 包只在該指定名字包的測試下使用 Export string // 包含導出數據的文件(當使用-export時) BuildID string // 編譯的包的構建ID(當使用-export時) Module *Module // 包包含的模塊的信息,如果有的話(可以為nil) Match []string // 匹配本包的命令行模式 DepOnly bool // 如為true,則包只是一個依賴,未在命令行中顯式列出 // 源文件 GoFiles []string // .go源文件(不包括CgoFiles、TestGoFiles、XTestGoFiles中的文件) CgoFiles []string // import "C"的.go源文件 CompiledGoFiles []string // 提交給編譯器的.go文件(當使用-compiled時) IgnoredGoFiles []string // 由於構建限制被忽略的.go源文件 IgnoredOtherFiles []string // 由於構建約束被忽略的非.go源文件 CFiles []string // .c源文件 CXXFiles []string // .cc/.cxx/.cpp源文件 MFiles []string // .m源文件 HFiles []string // .h/.hh/.hpp/.hxx源文件 FFiles []string // .f/.F/.for/.f90的Fortran源文件 SFiles []string // .s源文件 SwigFiles []string // .swig文件 SwigCXXFiles []string // .swigcxx文件 SysoFiles []string // 添加到歸檔的.syso對象文件 TestGoFiles []string // 包中的_test.go文件 XTestGoFiles []string // 包外的_test.go文件 // 嵌入文件 EmbedPatterns []string // //go:embed模式 EmbedFiles []string // 被EmbedPatterns匹配的文件 TestEmbedPatterns []string // TestGoFiles中的//go:embed模式 TestEmbedFiles []string // 被TestEmbedPatterns匹配的文件 XTestEmbedPatterns []string // XTestGoFiles中的//go:embed模式 XTestEmbedFiles []string // 被XTestEmbedPatterns匹配的文件 // Cgo指令 CgoCFLAGS []string // cgo:給C編譯器的標志 CgoCPPFLAGS []string // cgo:給C預編譯器的標志 CgoCXXFLAGS []string // cgo:給C++編譯器的標志 CgoFFLAGS []string // cgo:給Fortran編譯器的標志 CgoLDFLAGS []string // cgo:給鏈接器的標志 CgoPkgConfig []string // cgo:pkg-config名字 // 依賴信息 Imports []string // 本包使用的導入路徑 ImportMap map[string]string // 原始導入路徑到ImportPath的映射(標識入口信息被省略) Deps []string // 所有(遞歸的)導入依賴 TestImports []string // TestGoFiles使用的導入依賴 XTestImports []string // XTestGoFiles使用的導入依賴 // 錯誤信息 Incomplete bool // 本包或依賴包是否有錯誤 Error *PackageError // 加載本包的錯誤 DepsErrors []*PackageError // 加載依賴包的錯誤 }
vendor目錄中的包報告的ImportPath包括vendor目錄自身的路徑(例如,“d/vendor/p”而不是“p”),以便ImportPath唯一地標識一個給定包的副本。Imports、Deps、TestImports、和XTestImports列表同樣包含這種擴展的導入路徑。更多關於使用vendor的信息參閱golang.org/s/go15vendor。
錯誤信息,如果有的話,為:
type PackageError struct { ImportStack []string // 從命令行指定的包名到此的最短路徑 Pos string // 錯誤的位置(如果有的話為,文件名:行號:列號) Err string // 錯誤自身 }
模塊信息為一個Module結構體,其定義在下文的-m討論中。
模板函數“join”調用strings.Join。
模板函數“context”返回構建的上下文,定義如下:
type Context struct { GOARCH string // 目標體系結構 GOOS string // 目標操作系統 GOROOT string // GOROOT GOPATH string // GOPATH CgoEnabled bool // cgo是否可用 UseAllFiles bool // 是否使用所有文件,從而忽略使用+build指定行和文件名 Compiler string // 在計算目標路徑時假定的編譯器 BuildTags []string // 構建約束,用以匹配+build指定的行 ReleaseTags []string // 與當前發布版本兼容的發布版本 InstallSuffix string // 安裝目錄名字中使用的后綴 }
關於這些字段含義的更多信息,參閱go/build包的Context類型的文檔。
Dir、Target、Shlib、Root、ConflictDir和Export中的文件路徑均為絕對路徑。
默認情況下,GoFiles、CgoFiles等列表中的名字為Dir目錄中的文件(亦即,相對於Dir的路徑,而不是絕對路徑)。當使用-compiled和-test標志時添加的生成文件為指向生成的Go源代碼的緩存副本的絕對路徑。即使它們為Go源文件,路徑可能不是以“.go”結尾。
-
-find:找出指定名字的包但不解析它們的依賴:Imports和Deps列表將會為空。
-
-json:包數據以JSON格式打印,而不是使用template包的格式。
-
-m:列出模塊而不是包。
當列出模塊時,-f標志仍然指定一個應用於Go結構體的格式模板,但現在為一個Module結構體:
type Module struct { Path string // 模塊路徑 Version string // 模塊版本 Versions []string // 可獲得的模塊版本(當使用-versions時) Replace *Module // 被此模塊替代 Time *time.Time // 版本創建的時間 Update *Module // 可獲得的更新,如果有的話(當使用-u時) Main bool // 是否為主模塊? Indirect bool // 該模塊是否只為主模塊的間接依賴? Dir string // 該模塊保存文件的目錄,如果有的話 GoMod string // 該模塊go.mod文件的路徑,如果有的話 GoVersion string // 模塊中使用的go版本 Retracted string // 撤回信息,如果有的話(當使用-retracted或-u時) Error *ModuleError // 加載模塊時的錯誤 } type ModuleError struct { Err string // 錯誤自身 }
如果模塊在模塊緩存中或如果-modfile標志被使用,GoMod指向的文件可能在模塊目錄之外。
默認的輸出是打印模塊路徑,然后是關於版本和替代的信息,如果有的話。例如,“go list -m all”可能打印:
my/main/module golang.org/x/text v0.3.0 => /tmp/text rsc.io/pdf v0.1.1
Module結構體有一個String方法,用以格式化輸出的這一行,因此默認格式等同於-f '{{.String}}'。
注意,當模塊被替代,其Replace字段描述替代的模塊,其Dir字段設置為替代模塊的源代碼的目錄,如果有的話。(也就是說,如果Replace不為nil,那么Dir設置為Replace.Dir,無法訪問被替代的源代碼。)
list -m的參數會被解析為模塊的列表,而不是包的列表。主模塊是包含當前目錄的模塊。活躍的(active)模塊為主模塊及其依賴。不帶參數,list -m顯示主模塊。帶參數,list -m顯示參數指定的模塊。任何活躍的模塊都可以通過其模塊路徑指定。特殊的模式“all”指定所有活躍的模塊,首先是主模塊,然后是使用模塊路徑排序的依賴。包含“...”的模式指定其模塊路徑匹配該模式的活躍模塊。path@version形式的查詢指定該查詢的結果,不限於活躍的模塊。關於模塊查詢的更多信息,參閱“go help modules”。
模板函數“module”使用單個字符串參數,必須為模塊路徑或查詢,並以Module結構體的形式返回指定的模塊。如果發生錯誤,結果將是帶有非nil的Error字段的Module結構體。
-
-retracted:報告關於被撤回的模塊版本的信息。當-retracted與-f或-json一起使用,Retracted字段將被設置為一個字符串用以解釋為什么版本被撤回。該字符串從模塊的go.mod文件中的retract指令的注釋中提取。當-retracted和-versions一起使用時,被撤回的版本和未被撤回的版本一起列出。-retracted標志可與或者不與-m一起使用。
-
-test:不只是報告指定名字的包,也報告它們的測試二進制文件(對帶有測試的包),從而將測試二進制文件是怎樣構建的准確地傳遞給源代碼分析工具。測試二進制文件的報告的導入路徑為包的導入路徑添加“.test”后綴,如“math/rand.test”。當構建測試時,有時候需要重新構建測試特定的某些依賴(最常見的是被測試的包本身)。為特定的測試二進制文件重新編譯的包的報告的導入路徑,會添加一個空格和以括號括起的測試二進制文件的名字,如“math/rand [math/rand.test]”或“regexp [sort.test]”。ForTest也會設置為正在被測試的包名(在此前的例子中為“math/rand”或“sort”)。
-
-u:添加關於可用升級的信息。當給定模塊的最后版本比當前模塊較新時,-u設置Module的Update字段為關於較新模塊的信息。如果當前版本被撤回,-u也會設置Module的Retracted字段。通過在當前版本后面格式化以括號括起的較新版本,Module的String方法表示一個可獲得的升級。如果版本被撤回,其后跟字符串“(retracted)”。例如,“go list -m -u all”可能打印:
my/main/module golang.org/x/text v0.3.0 [v0.4.0] => /tmp/text rsc.io/pdf v0.1.1 (retracted) [v0.1.2]
(對工具來說,“go list -m -u -json all”可能更便於解析。)
-
-versions:設置Module的Versions字段為該模塊的所有已知版本的列表,根據語義版本進行排序,從最早至最后。該標志也會改變默認的輸出格式來顯示模塊路徑,其后接着以空格分隔的版本列表。
關於構建標志的更多信息,參閱“go help build”。
關於指定包的更多信息,參閱“go help packages”。
關於模塊的更多信息,參閱https://golang.org/ref/mod。
go mod——模塊維護
go mod <command> [arguments]
command可為以下命令:
- download:下載模塊至本地緩存中。
- edit:通過工具或腳本編輯go.mod。
- graph:打印模塊依賴圖。
- init:在當前目錄初始化新模塊。
- tidy:添加缺少的模塊並刪除未使用的模塊。
- vendor:生成依賴的vendor副本。
- verify:驗證依賴有預期的內容。
- why:解釋為什么需要該包或模塊。
go mod提供對模塊操作的訪問。
注意對模塊的支持內置於所有go命令,不只是“go mod”。例如,依賴的日常添加、刪除、升級、降級應該使用“go get”來完成。關於模塊功能的概述,參閱“go help modules”。
關於命令的更多信息,參閱“go help mod
go mod download——下載模塊至本地緩存中
go mod download [-x] [-json] [modules]
download下載指定名字的模塊,可為選擇主模塊依賴的模塊匹配模式,或path@version形式的模塊查詢。不帶參數,download應用於主模塊的所有依賴。
go命令將在常規執行期間根據需要自動下載模塊。“go mod download”命令主要用於預填充本地緩存或計算Go模塊代理的結果。
默認情況下,download不向標准輸出寫入內容。其可能打印進度信息和錯誤至標准錯誤輸出。
標志:
-
-json:打印一系列JSON對象至標准輸出,描述每個下載的模塊(或失敗),相當於該Go結構體:
type Module struct { Path string // 模塊路徑 Version string // 模塊版本 Error string // 加載模塊時的錯誤 Info string // 緩存的.info文件絕對路徑 GoMod string // 緩存的.mod文件絕對路徑 Zip string // 緩存的.zip文件絕對路徑 Dir string // 緩存的源文件根目錄絕對路徑 Sum string // 路徑、版本的校驗和(如go.sum中所示) GoModSum string // go.mod的校驗和(如go.sum中所示) }
-
-x:打印實際需執行的命令,並運行。
關於“go mod download”的更多信息,參閱https://golang.org/ref/mod#go-mod-download。
關於版本查詢的更多信息,參閱https://golang.org/ref/mod#version-queries。
go mod edit——通過工具或腳本編輯go.mod
go mod edit [editing flags] [go.mod]
edit提供一個編輯go.mod的命令行接口,主要提供給工具或腳本使用。它只讀取go.mod;不查找涉及模塊的信息。默認情況下,edit讀寫主模塊的go.mod文件,但也可以在標志后指定不同的目標文件。
標志:
-
-dropexclude=path@version:刪除給定模塊路徑和版本的排除。
-
-dropreplace=old[@v]:刪除給定模塊路徑和版本的替代。如果@v省略,刪除該模塊不帶版本的替代。
-
-droprequire=path:刪除給定的模塊路徑依賴的模塊。該標志主要提供給工具用以理解模塊圖。用戶應該使用“go get path@none”,可令其它go.mod根據需要調整來滿足其它模塊施加的限制。
-
-dropretract=version:刪除對給定版本的撤回。version可能是類似“v1.2.3”的單個版本或類似“[v1.1.0,v1.1.9]”的閉區間。
-
-exclude=path@version:添加給定模塊路徑和版本的排除。注意如果排除已經存在-exclude=path@version是無操作的。
-
-fmt:重新格式化go.mod文件,不作其他改變。使用或重寫go.mod文件的任何其他修改也意味着這種重新格式化。需要該標志的唯一情形是沒有指定其它標志,如“go mod edit -fmt”。
-
-go=version:設置期望的Go語言版本。
-
-json:以JSON格式打印最終的go.mod,而不是將其寫回go.mod。JSON輸出對應於這些Go類型:
type Module struct { Path string Version string } type GoMod struct { Module Module Go string Require []Require Exclude []Module Replace []Replace Retract []Retract } type Require struct { Path string Version string Indirect bool } type Replace struct { Old Module New Module } type Retract struct { Low string High string Rationale string }
表示單個版本(不是一個區間)的Retract條目將有設置為相同值的“Low”和“High”字段。
-
-module:修改模塊路徑(go.mod文件的模塊行)。
-
-print:以其文本格式打印最終的go.mod,而不是將其寫回go.mod。
-
-replace=old[@v]=new[@v]:添加給定模塊路徑和版本對的替代。如果old@v中的@v省略,則左側不帶版本的替代將被添加,應用於old模塊路徑的所有版本。如果new@v中的@v省略,新路徑應為本地模塊根目錄,而不是模塊路徑。注意-replace覆蓋old[@v]任何冗余的替代,因此省略@v將刪除對特定版本的現有替代。
-
-require=path@version:添加給定的模塊路徑和版本依賴的模塊。注意-require覆蓋該路徑任何已存在的依賴的模塊。該標志主要提供給工具用以理解模塊圖。用戶應該使用“go get path@version”,其可令其它go.mod根據需要調整來滿足其它模塊施加的限制。
-
-retract=version:添加對給定版本的撤回。version可能是類似“v1.2.3”的單個版本或類似“[v1.1.0,v1.1.9]”的閉區間。注意如果撤回已經存在-retract=version是無操作的。
-require、-droprequire、-exclude、-dropexclude、-replace、-dropreplace、-retract、-dropretract編輯標志可以重復,根據給定的順序應用修改。
注意這只描述go.mod文件自身,不描述其他間接引用的模塊。對於構建可使用的的模塊的完整集合,使用“go list -m -json all”。
關於“go mod edit”的更多信息參閱https://golang.org/ref/mod#go-mod-edit。
go mod graph——打印模塊依賴圖
go mod graph
以文本形式打印模塊依賴圖(已應用替代)。輸出的每行有兩個空格分隔的字段:模塊和其依賴中的一個。每個模塊都被標記為path@version形式的字符串,除了主模塊,因其沒有@version后綴。
關於“go mod graph”的更多信息參閱https://golang.org/ref/mod#go-mod-graph。
go mod init——在當前目錄初始化新模塊
go mod init [module]
初始化並寫入一個新的go.mod文件至當前目錄中,實際上是創建一個以當前目錄為根的新模塊。文件go.mod必須不存在。
接受一個可選參數,即新模塊的模塊路徑。如果模塊路徑參數省略,將使用.go文件中的import注釋、vendoring工具配置文件(類似Gopkg.lock)和當前目錄(如果在GOPATH中)嘗試推斷模塊路徑。
如果vendoring工具配置文件存在,將嘗試從其導入模塊依賴。
關於“go mod init”的更多信息參閱https://golang.org/ref/mod#go-mod-init。
go mod tidy——添加缺少的模塊並刪除未使用的模塊
go mod tidy [-e] [-v]
確保go.mod與模塊中的源代碼一致。它添加構建當前模塊的包和依賴所必須的任何缺少的模塊,刪除不提供任何有價值的包的未使用的模塊。它也會添加任何缺少的條目至go.mod並刪除任何不需要的條目。
標志:
- -e:即使有加載包時遇到的錯誤仍嘗試繼續。
- -v:打印被刪除的模塊的信息至標准錯誤輸出。
關於“go mod tidy”的更多信息參閱https://golang.org/ref/mod#go-mod-tidy。
go mod vendor——生成依賴的vendor副本
go mod vendor [-e] [-v]
重置主模塊的vendor目錄,使其包含構建和測試所有主模塊的包所需要的所有包。不包括vendor中的包的測試代碼。
- -e:即使有加載包時遇到的錯誤仍嘗試繼續。
- -v:打印vendor的模塊和包的名字至標准錯誤輸出。
關於“go mod vendor”的更多信息參閱https://golang.org/ref/mod#go-mod-vendor。
go mod verify——驗證依賴有預期的內容
go mod verify
檢查存儲在本地下載源代碼緩存中的當前模塊的依賴,是否自從下載之后未被修改。如果所有模塊都未被修改,打印“all modules verified”。否則報告哪個模塊已經被修改並令“go mod”以非0狀態退出。
關於“go mod verify”的更多信息參閱https://golang.org/ref/mod#go-mod-verify。
go mod why——解釋為什么需要該包或模塊
go mod why [-m] [-vendor] packages...
標志:
- -m:默認情況下,why在導入圖中展示從主模塊到每個列出的包的最短路徑。如果給出-m標志,why將參數視為一個模塊的列表並找出每個模塊中的所有包的路徑。
- -vendor:默認情況下,why查詢與“go list all”匹配的包圖,包括對可達包的測試相關的包。-vendor標志令why將依賴包的測試相關的包排除在外。
輸出是一系列的小節,和命令行中每個包或模塊的名字一一對應,以空行分隔。每個小節以注釋行“# package”或“# module”開頭,給出目標包或模塊。隨后的行通過導入圖給出路徑,一個包一行。如果包或模塊沒有被主模塊引用,該小節將顯示單獨一個帶圓括號的提示信息來表明該事實。
例如:
$ go mod why golang.org/x/text/language golang.org/x/text/encoding
# golang.org/x/text/language
rsc.io/quote
rsc.io/sampler
golang.org/x/text/language
# golang.org/x/text/encoding
(main module does not need package golang.org/x/text/encoding)
$
關於“go mod why”的更多信息參閱https://golang.org/ref/mod#go-mod-why。
go run——編譯並運行Go程序
go run [build flags] [-exec xprog] package [arguments...]
編譯並運行指定名字的main Go包。通常包是作為一個單獨的目錄中的.go源文件列表指定的,但也可以是導入路徑、文件系統路徑、或匹配單獨的已知包的模式,例如“go run .”或“go run my/cmd”。
標志:
-
-exec:默認情況下,“go run”直接運行編譯的二進制文件:“a.out arguments...”。如果給定-exec標志,“go run”使用xprog調用二進制文件:“xprog a.out arguments...”。
如果-exec標志未給定,GOOS或GOARCH與系統默認值不同,一個名字為go_$GOOS_$GOARCH_exec的程序可在當前查找目錄下找到,“go run”使用該程序調用二進制文件,如“go_nacl_386_exec a.out arguments...”。當模擬器或其他執行方法可用時,這允許交叉編譯的程序執行。
run的退出狀態不是編譯的二進制文件的退出狀態。
關於構建標志的更多信息,參閱“go help build”。關於指定包的更多信息,參閱“go help packages”。
參閱:go build。
go test——測試包
go test [build/test flags] [packages] [build/test flags & test binary flags]
“go test”自動測試以導入路徑命名的包。它以如下格式打印測試結果概要:
ok archive/tar 0.011s
FAIL archive/zip 0.022s
ok compress/gzip 0.033s
...
每個失敗的包后跟隨詳細的輸出。
“go test”將與名字匹配文件模式“*test.go”的任何文件一起,重新編譯每個包。這些附加的文件可以包含test函數、benchmark函數、example函數。更多信息參閱“go help testfunc”。每個列出的包都會令到執行單獨的測試二進制文件。以“”(包括“_test.go”)或“.”開頭的文件會被忽略。
帶后綴“_test”聲明的包的測試文件將被編譯為單獨的包,然后與main包的測試二進制文件鏈接並運行。
go tool將忽略名字為“testdata”的目錄,令其可以持有被測試所需的輔助數據。
作為構建測試二進制文件的一部分,go test在包及其測試源文件上運行go vet來發現顯而易見的問題。如果go vet發現任何問題,go test報告它們且不運行測試二進制文件。只使用默認的go vet檢查的高可信的子集。該子集是:“atomic”、“bool”、“buildtags”、“nilfunc”和“printf”。你可以通過“go doc cmd/vet”查看這些及其它vet測試的文檔。要禁止運行go vet,使用-vet=off標志(參閱 testflag主題——測試標志 小節)。
所有的測試輸出和概要行都打印至go命令的標准輸出,即使test打印它們至它自己的標准錯誤輸出。(go命令的標准錯誤輸出被保留為打印構建測試的錯誤。)
go test以兩種不同的模式運行:
第一種,稱為本地目錄模式,發生在當go test不使用包參數調用時(例如,“go test”或“go test -v”)。在這種模式下,go test編譯在當前目錄下找到的包源文件和測試文件,然后運行生成的測試二進制文件。在這種模式下,緩存(在下面討論)被禁用。包測試完成后,go test打印一行概要行展示測試狀態(“ok”或“FAIL”)、包名和消耗的時間。
第二種,稱為包列表模式,發生在當go test使用顯式的包參數調用時(例如“go test math”、“go test ./...”甚至“go test .”)。在這種模式下,go test編譯並測試每個在命令行列出的包。如果一個包測試通過,go test只打印最終的“ok”概要行。如果一個包測試失敗,go test打印完整的測試輸出。如果使用-bench或-v標志調用(參閱 testflag主題——測試標志 小節),即使通過了包測試,go test也打印完整的輸出,以便展示要求的基准測試結果或詳細日志。對所有列出的包的包測試完成后,且它們的輸出被打印,如果任一個包測試失敗,go test打印最終的“FAIL”狀態。
只在包列表模式,go test緩存成功的包測試結果來避免不必要的測試重復運行。當測試的結果可以從緩存恢復時,go test將重新展示之前的輸出而不是再次運行測試二進制文件。當這種情況發生時,go test在概要行中打印“(cached)”取代消耗的時間。
緩存匹配的規則為,運行只涉及相同的測試二進制文件,且命令行中的標志完全來自一個受限的“可緩存”測試標志集合,定義為-cpu、-list、-parallel、-run、-short和-v。如果go test的運行有任何不在這個集合中的測試或非測試標志,結果是不被緩存的。要禁用測試緩存,使用可緩存標志以外的測試標志或參數。顯式禁用測試緩存的慣用方式為使用-count=1。在包源代碼根目錄(通常為$GOPATH)內打開文件或查詢環境變量的測試只匹配將來的文件和環境變量未改變的測試運行。緩存的測試結果被視為立即執行的,因此一個成功的包測試結果將被緩存且重用時忽略-timeout設置。
除了構建標志,“go test”自身處理的標志還有:
- -args:傳遞命令行中余下的參數(所有在-args后面的參數)至測試二進制文件,不解析且不修改。因為該標志使用命令行中余下的參數,包列表(如果有)必須出現在該標志之前。
- -c:編譯測試二進制文件為pkg.test但不運行之(pkg是包的導入路徑的最后的元素)。文件名可以被-o標識修改。
- -exec xprog:使用xprog運行測試二進制文件。其行為與“go run”相同。詳細信息參閱“go help run”。
- -i:安裝測試的依賴包。不運行測試。-i標志被反對使用。已編譯的包會被自動緩存。
- -json:轉換測試輸出為適合自動化執行的JSON格式。關於編碼的詳細信息參閱“go doc test2json”。
- -o file:編譯測試二進制文件至指定名字的文件。測試仍會運行(除非指定-c或-i)。
測試二進制文件也接受控制測試執行的標志;這些參數也可被“go test”使用。詳細信息參閱“go help testflag”。
關於構建標志的更多信息,參閱“go help build”。關於指定包的更多信息,參閱“go help packages”。
參閱:go build、go vet。
go tool——運行指定的go tool
go tool [-n] command [args...]
運行參數指定的go tool命令。不帶參數則打印已知的工具列表。
標志:
- -n:打印將會執行的命令但不執行之。
關於每個tool命令的更多信息,參閱“go doc cmd/
go version——打印Go版本
go version [-m] [-v] [file ...]
打印Go可執行文件的構建信息。
go version報告用來構建每個指定名字的可執行文件的Go版本。
如果命令行中沒有指定文件,go version打印其自身的版本信息。
標志:
- -m:當可以獲得的時候,令go version打印每個可執行文件的內嵌的模塊版本信息。在輸出中,模塊信息包含跟在版本行之后的多行,每行由前導制表符縮進。
- -v:如果指定一個目錄,go version遞歸地遍歷該目錄,查找可以識別的Go二進制文件並報告它們的版本。默認情況下,go version不報告在目錄掃描期間發現的無法識別的文件。-v標志令其報告無法識別的文件。
參閱:go doc runtime/debug.BuildInfo。
go vet——報告包中有可能的錯誤
go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]
在通過導入路徑指定名字的包上運行go vet命令。
關於vet和其標志的更多信息,參閱“go doc cmd/vet”。關於指定包的更多信息,參閱“go help packages”。關於檢查程序及其標志的列表,參閱“go tool vet help”。關於諸如“printf”的特定檢查程序的詳細信息,參閱“go tool vet help printf”。
標志:
-
-n:打印將會執行的命令但不執行之。
-
-vettool=prog:選擇帶有備選或附加檢查的不同的分析工具。例如,可以使用這些命令來構建和運行“shadow”分析器:
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow go vet -vettool=$(which shadow)
-
-x:打印將會執行的命令並執行之。
go vet支持的構建標志是那些控制包解析和執行的標志,如-n、-x、-v、-tags和-toolexec。關於這些標志的更多信息,參閱“go help build”。
參閱:go fmg、go fix。
buildconstraint主題——構建約束
構建約束(constraint),也被認為是構建標記(tag),是以此開始的一行:
// +build
其列出文件應該被包含在包中的條件。約束可以出現在任何類型的源文件中(不只是Go),但它們必須出現在文件的頂部附近,在其前面只有空行或其它行注釋。這些規則意味着在Go文件中構建約束必須出現在package語句之前。
為了區分構建約束和包文檔,一連串的構建約束必須后接一個空行。
構建約束視作空格分隔選項的OR關系。每個選項視作逗號分隔項的AND關系。每個項由字母、數字、下划線和點組成。項可以用前導的“!”否定。例如,構建約束:
// +build linux,386 darwin,!cgo
對應布爾算式:
(linux AND 386) OR (darwin AND (NOT cgo))
一個文件可以有多個構建約束。整體的約束是單獨的約束的AND關系。亦即,構建約束:
// +build linux darwin
// +build amd64
對應布爾算式:
(linux OR darwin) AND amd64
在特定的構建期間,以下的詞匯是可用的:
- 目標操作系統,即為runtime.GOOS顯示的值,使用GOOS環境變量設置。
- 目標體系結構,即為runtime.GOARCH顯示的值,使用GOARCH環境變量設置。
- 使用的編譯器,“gc”或“gccgo”之一。
- “cgo”,如果支持cgo命令(參閱“go help environment”中的CGO_ENABLED)。
- 可表示直到當前版本的每一個Go主版本(譯注:示例不是次版本?)的發布版本的項:“go1.1”為從Go版本1.1開始,“go1.12”為從Go版本1.12開始,依次類推。
- 被-tags標志指定的任何額外的標記(參閱“go help build”)。
beta或次版本(譯注:不是修訂版本?)的發布版本沒有單獨的構建標記。
如果文件名,在去掉擴展名和可能的_test后綴后,匹配任意下述的模式:
- *_GOOS
- *_GOARCH
- *_GOOS_GOARCH
(例如:source_windows_amd64.go)此處的GOOS和GOARCH分別表示任意已知的操作系統和體系結構值,那么該文件被認為有要求這些項的隱式的構建約束(加上文件中任何顯式的約束)。
使用GOOS=android匹配關於GOOS=linux的構建標記和文件,並加上android標記和文件。
使用GOOS=illumos匹配關於GOOS=solaris的構建標記和文件,並加上illumos標記和文件。
使用GOOS=ios匹配關於GOOS=darwin的構建標記和文件,並加上ios標記和文件。
要使文件在構建時不被考慮:
// +build ignore
(任何其它不滿足規則的詞匯也會同樣工作,但“ignore”是按照慣例的。)
要只在使用cgo時,以及只在Linux和OS X上構建文件:
// +build linux,cgo darwin,cgo
這樣的文件通常與為其它系統實現默認功能的另一個文件搭配,在這個示例下將帶有約束:
// +build !linux,!darwin !cgo
命名文件為dns_windows.go將令其只在為Windows構建包時被包含;類似地,math_386.s將只在為32位x86構建包時被包含。
buildmode主題——構建模式
“go build”和“go install”命令使用-buildmode參數,用來表示要構建哪一種對象文件。當前支持的值為:
(譯注:下述構建模式如無特別說明,均可列出多個包同時構建。)
- -buildmode=archive:構建列出的非main包生成.a文件。main包被忽略。
- -buildmode=c-archive:構建列出的main包,加上其導入的所有包,生成C歸檔文件。可調用的符號只為那些使用cgo的// export注釋導出的函數。要求只能列出一個main包。
- -buildmode=c-shared:構建列出的main包,加上其導入的所有包,生成C共享庫。可調用的符號只為那些使用cgo的// export注釋導出的函數。要求只能列出一個main包。
- -buildmode=default:構建列出的main包生成可執行文件,構建列出的非main包生成.a文件(默認行為)。
- -buildmode=exe:構建列出的main包及其導入的所有包生成可執行文件。非main包被忽略。
- -buildmode=pie:構建列出的main包及其導入的所有包生成地址無關可執行文件(position independent executables,即PIE)。非main包被忽略。
- -buildmode=plugin:構建列出的main包,加上其導入的所有包,生成Go插件(plugin)。非main包被忽略。
- -buildmode=shared:合並所有列出的非main包生成單獨的共享庫,共享庫可在當使用-linkshared選項構建時使用。main包被忽略。
在AIX上,當鏈接使用以-buildmode=c-archive構建的Go歸檔文件的C程序時,必須傳遞-Wl,-bnoobjreorder至C編譯器。
c主題——Go和C之間的調用
有兩種不同的方式在Go和C/C++代碼之間調用。
第一種方式是cgo工具,它是Go發行版的一部分。關於如何使用它的信息參閱cgo文檔(go doc cmd/cgo)。
第二種是SWIG程序,它是語言之間通過接口連接的通用工具。關於SWIG的信息參閱http://swig.org/。當運行go build時,任何帶有.swig擴展名的文件將傳遞給SWIG。任何帶.swigcxx擴展名的文件將使用-c++選項傳遞給SWIG。
當cgo或SWIG任一種被使用時,go build將傳遞所有.c、.m、.s或.S文件至C編譯器,以及所有.cc、.cpp、.cxx文件至C++編譯器。可以設置CC或CXX環境變量來依次決定要使用的C或C++編譯器。
cache主題——構建和測試緩存
go命令緩存構建輸出以在將來的構建中重用。緩存數據的默認位置為當前操作系統標准用戶緩存目錄下名字為go-build的子目錄。設置GOCACHE環境變量覆蓋該默認值,運行“go env GOCACHE”打印當前緩存目錄。
go命令定期地刪除最近未使用的緩存數據。運行“go clean -cache”刪除所有緩存數據。
構建緩存會正確地考慮Go源文件、編譯器、編譯器選項等等的改變:在平常的使用中顯式地清理緩存不是必須的。但是,構建緩存不檢測由cgo導入的C庫的改變。如果你在你的系統上對C庫進行了修改,你將需要顯式地清理緩存或使用-a構建標志(參閱“go help build”)來強制重新構建那些依賴已經更新了的C庫的包。
go命令也緩存成功的包測試結果。更多細節參閱“go help test”。運行“go clean -testcache”刪除所有緩存的測試結果(不包括緩存的構建結果)。
GODEBUG環境變量可以啟用關於緩存狀態調試信息的打印:
- GODEBUG=gocacheverify=1:令go命令繞過任何緩存條目的使用,取而代之重新構建所有內容並檢查結果是否與現有的緩存條目匹配。
- GODEBUG=gocachehash=1:令go命令打印為其使用來構建緩存查找鍵的所有內容哈希值的輸入。輸出是冗長的但能對調試緩存有用。
- GODEBUG=gocachetest=1:令go命令打印其關於是否重用緩存測試結果的決策的詳細信息。
environment主題——環境變量
go命令及其調用的工具查詢環境變量以進行配置。如果環境變量未設置,go命令使用一個合理的默認設置。要查看變量
通用的環境變量:
- GCCGO:為“go build -compiler=gccgo”運行的gccgo命令。
- GO111MODULE:控制go命令運行在模塊感知模式還是GOPATH模式。可為“off”、“on”或“auto”。參閱https://golang.org/ref/mod#mod-commands。
- GOARCH:要為之編譯代碼的體系結構或處理器。例如amd64、386、arm、ppc64。
- GOBIN:“go install”安裝命令使用的目錄。
- GOCACHE:go命令存儲緩存信息用以在將來的構建中重用的目錄。
- GODEBUG:啟用多種調試功能。詳細信息參閱“go doc runtime”。
- GOENV:Go環境變量配置文件位置。不能使用“go env -w”設置。
- GOFLAGS:一個空白分隔的-flag=value設置列表,當給定的標志被當前命令已知時,會被默認應用於go命令。每個條目必須是單獨的標志。因為條目是空白分隔的,標志值必須不包含空白。在命令行列出的標志在這個列表之后應用並因此覆蓋之。
- GOINSECURE:模塊路徑前綴的glob模式(以Go的path.Match的語法)的逗號分隔的列表,其應總是以不安全的方式拉取。只應用於被直接拉取的依賴。不像“go get”的-insecure標志,GOINSECURE不禁用校驗和數據庫驗證。GOPRIVATE或GONOSUMDB可以用來達到該目的。
- GOMODCACHE:go命令存儲下載的模塊的目錄。
- GONOPROXY:(譯注:模塊路徑前綴的glob模式(以Go的path.Match的語法)的逗號分隔的列表,其不使用模塊代理下載。參閱https://golang.org/ref/mod#private-modules。)
- GONOSUMDB:(譯注:模塊路徑前綴的glob模式(以Go的path.Match的語法)的逗號分隔的列表,其不使用校驗和數據庫進行校驗。參閱https://golang.org/ref/mod#private-modules。)
- GOOS:要為之編譯代碼的操作系統。例如linux、darwin、windows、netbsd。
- GOPATH:更新詳細信息參閱:“go help gopath”。
- GOPRIVATE:模塊路徑前綴的glob模式(以Go的path.Match的語法)的逗號分隔的列表,其應該總是直接拉取或不應該與校驗和數據庫比較。參閱https://golang.org/ref/mod#private-modules。
- GOPROXY:Go模塊代理URL。詳細信息參閱https://golang.org/ref/mod#environment-variables和https://golang.org/ref/mod#module-proxy。
- GOROOT:go樹的根。
- GOSUMDB:使用的校驗和數據庫的名字,及可選的其公鑰和URL。參閱https://golang.org/ref/mod#authenticating。
- GOTMPDIR:go命令寫入臨時源文件、包和二進制文件的目錄。
- GOVCS:列出可與匹配的服務器一起使用的版本控制命令。參閱“go help vcs”。
與cgo一起使用的環境變量:
- AR:當使用gccgo編譯器構建時用來操作庫歸檔文件的命令。默認為“ar”。
- CC:用來編譯C代碼的命令。
- CGO_CFLAGS:當編譯C代碼時cgo將傳遞給編譯器的標志。
- CGO_CFLAGS_ALLOW:一個正則表達式,用來指定允許出現在#cgo CFLAGS源代碼指令中的附加標志。不會應用於CGO_CFLAGS環境變量。
- CGO_CFLAGS_DISALLOW:一個正則表達式,指定必須被禁止出現在#cgo CFLAGS源代碼指令中的標志。不會應用於CGO_CFLAGS環境變量。
- CGO_CPPFLAGS:類似CGO_CFLAGS,但提供給C預處理器。
- CGO_CPPFLAGS_ALLOW:類似CGO_CFLAGS_ALLOW,但提供給C預處理器。
- CGO_CPPFLAGS_DISALLOW:類似CGO_CFLAGS_DISALLOW,但提供給C預處理器。
- CGO_CXXFLAGS:類似CGO_CFLAGS,但提供給C++編譯器。
- CGO_CXXFLAGS_ALLOW:類似CGO_CFLAGS_ALLOW,但提供給C++編譯器。
- CGO_CXXFLAGS_DISALLOW:類似CGO_CFLAGS_DISALLOW,但提供給C++編譯器。
- CGO_ENABLED:cgo命令是否支持。0或1。
- CGO_FFLAGS:類似CGO_CFLAGS,但提供給Fortran編譯器。
- CGO_FFLAGS_ALLOW:類似CGO_CFLAGS_ALLOW,但提供給Fortran編譯器。
- CGO_FFLAGS_DISALLOW:類似CGO_CFLAGS_DISALLOW,但提供給Fortran編譯器。
- CGO_LDFLAGS:類似CGO_CFLAGS,但提供給鏈接器。
- CGO_LDFLAGS_ALLOW:類似CGO_CFLAGS_ALLOW,但提供給鏈接器。
- CGO_LDFLAGS_DISALLOW:類似CGO_CFLAGS_DISALLOW,但提供給鏈接器。
- CXX:用來編譯C++代碼的命令。
- FC:用來編譯Fortran代碼的命令。
- PKG_CONFIG:pkg-config工具的路徑。
體系結構特定的環境變量:
- GO386:對GOARCH=386,如何實現浮點指令。有效值為sse2(默認)、softfloat。
- GOARM:對GOARCH=arm,要為之編譯的ARM體系結構。有效值為5、6、7。
- GOMIPS:對GOARCH=mips{,le},是否使用浮點指令。有效值為hardfloat(默認)、softfloat。
- GOMIPS64:對GOARCH=mips64{,le},是否使用浮點指令。有效值為hardfloat(默認)、softfloat。
- GOWASM:對GOARCH=wasm,要使用的實驗性WebAssembly特性的逗號分隔的列表。有效值為satconv、signext。
特殊用途的環境變量:
- GCCGOTOOLDIR:如果設置,表示在哪可以找到gccgo工具,例如cgo。默認值基於gccgo是怎么配置的。
- GIT_ALLOW_PROTOCOL:由Git定義。允許與git fetch/clone一起使用的冒號分隔的方案(scheme)列表。如果設置,任何未明確提及的方案會被“go get”認為是不安全的。因為該變量是被Git定義,默認值不可以使用“go env -w”設置。
- GO_EXTLINK_ENABLED:當與使用cgo的代碼一起使用-linkmode=auto時,鏈接器是否應該使用外部鏈接模式。設為0禁用外部鏈接模式,1為啟用之。
- GOROOT_FINAL:已安裝的Go樹的根,用在當其安裝在其構建位置以外的地方時。堆棧跟蹤中的文件名從GOROOT重寫為GOROOT_FINAL。
從“go env”可獲得的附加信息但不是從環境變量讀取的:
- GOEXE:可執行文件名后綴(在Windows上為“.exe”,在其它系統上為“”)。
- GOGCCFLAGS:提供給CC命令的空白分隔的參數列表。
- GOHOSTARCH:Go工具鏈二進制文件的體系結構(GOARCH)。
- GOHOSTOS:Go工具鏈二進制文件的操作系統(GOOS)。
- GOMOD:主模塊的go.mod的絕對路徑。如果模塊感知模式啟用,但沒有go.mod,GOMOD將為os.DevNull(在類Unix系統上為“/dev/null”,在Windows上為“NUL”)。如果模塊感知模式禁用,GOMOD將為空字符串。
- GOTOOLDIR:go工具(compile、cover、doc等等)安裝的目錄。
- GOVERSION:已安裝的Go樹的版本,如同runtime.Version所報告的一樣。
filetype主題——文件類型
go命令檢查每個目錄中限定的一組文件的內容。其根據文件名的擴展名識別哪些文件要檢查。這些擴展名為:
- .c/.h:C源文件。如果包使用cgo或SWIG,這些文件將使用操作系統本地編譯器(通常為gcc)編譯;否則它們將觸發一個錯誤。
- .cc/.cpp/.cxx/.hh/.hpp/.hxx:C++源文件。只在使用cgo或SWIG時有用,並總是使用操作系統本地編譯器編譯。
- .go:Go源文件。
- .m:Objective-C源文件。只在使用cgo時有用,並總是使用操作系統本地編譯器編譯。
- .s/.S/.sx:匯編源文件。如果包使用cgo或SWIG,它們將使用操作系統本地匯編器(通常為gcc(sic))匯編;否則它們將使用Go匯編器匯編。
- .swig/.swigcxx:SWIG定義文件。
- .syso:系統對象文件。
這些類型除.syso之外的每個類型的文件都可能包含構建約束,但go命令在文件中不是空行或//-style行注釋的第一項處停止掃描構建約束。更多詳細信息參閱go/build包文檔。
go.mod主題——go.mod文件
模塊版本是由源文件樹定義的,在其根目錄中有一個go.mod文件。當go命令運行時,它查找當前目錄並然后查找相繼的父目錄來找出go.mod,go.mod標記主(當前)模塊的根。
go.mod文件格式在https://golang.org/ref/mod#go-mod-file中詳細地描述。
要創建一個新的go.mod文件,使用“go mod init”(譯注:原文為“go help init”有誤)。詳細信息參閱“go help mod init”或https://golang.org/ref/mod#go-mod-init。
要添加缺失的模塊依賴或刪除不需要的依賴,使用“go mod tidy”。詳細信息,參閱“go help mod tidy”或https://golang.org/ref/mod#go-mod-tidy。
要添加、升級、降級、刪除特定的模塊依賴,使用“go get”。詳細信息,參閱“go help module-get”或https://golang.org/ref/mod#go-get。
要進行其它更改或要以JSON解析go.mod以供其它工具使用,使用“go mod edit”。參閱“go help mod edit”或https://golang.org/ref/mod#go-mod-edit。
gopath主題——GOPATH環境變量
(譯注:當使用GOPATH模式時,GOPATH用於解析import導入;當使用模塊感知模式時,GOPATH不用於解析import導入。)
GOPATH用於解析import語句,其被go/build包實現並在go/build包中記錄文檔。
GOPATH環境變量列出查找Go代碼的位置。在Unix上,值是冒號分隔的字符串。在Windows上,值是分號分隔的字符串。在Plan 9上,值是一個列表。
如果環境變量未設置,GOPATH默認為在用戶的主目錄中名字為“go”的子目錄(在Unix上為$HOME/go,在Windows上為%USERPROFILE%\go),除非該目錄包含Go發行版。運行“go env GOPATH”來查看當前的GOPATH。
參閱https://golang.org/wiki/SettingGOPATH來設置自定義GOPATH。
GOPATH中列出的每個目錄必須有規定的結構:
-
src目錄包含源代碼。src下的路徑決定import路徑或可執行文件名。
-
pkg目錄包含安裝的包對象文件。如同在Go樹中,每個目標操作系統和體系結構對都有其自己的pkg子目錄(pkg/GOOS_GOARCH)。
如果DIR是GOPATH中列出的一個目錄,源代碼在DIR/src/foo/bar中的包可以被導入為“foo/bar”並且其編譯形式的文件會被安裝到“DIR/pkg/GOOS_GOARCH/foo/bar.a”。
-
bin目錄包含編譯的命令。每個命令以其源代碼目錄命名,但只取最后一個元素,不是全部的路徑。亦即,源代碼在DIR/src/foo/quux中的命令被安裝至DIR/bin/quux,而不是DIR/bin/foo/quux。“foo/”前綴被剝掉,因此你可以添加DIR/bin至你的PATH中來訪問安裝的命令。如果GOBIN環境變量被設置,命令會被安裝至其命名的目錄而不是DIR/bin。GOBIN必須為絕對路徑。
這是一個示例目錄布局:
GOPATH=/home/user/go
/home/user/go/
src/
foo/
bar/ (bar包中的go代碼)
x.go
quux/ (main包中的go代碼)
y.go
bin/
quux (安裝的命令)
pkg/
linux_amd64/
foo/
bar.a (安裝的包對象文件)
go搜索GOPATH中列出的每個目錄來查找源代碼,但新的包總是下載至列表中的第一個目錄。
示例參閱https://golang.org/doc/code.html。
GOPATH和模塊
當使用模塊時,GOPATH不再用來解析import導入。然而,其仍然會被用來保存下載的源代碼(在GOPATH/pkg/mod中)和編譯的命令(在GOPATH/bin中)。
internal目錄
(譯注:使用GOPATH模式和模塊感知模式,均可使用internale目錄。)
在名為“internal”目錄中或以下的代碼只可以被以“internal”的父目錄為根的目錄樹中的代碼導入。這是上面的目錄布局擴展版本:
/home/user/go/
src/
crash/
bang/ (bang包中的go代碼)
b.go
foo/ (foo包中的go代碼)
f.go
bar/ (bar包中的go代碼)
x.go
internal/
baz/ (baz包中的go代碼)
z.go
quux/ (main包中的go代碼)
y.go
z.go中的代碼被導入為“foo/internal/baz”,但該import導入語句只能出現在以foo為根的子樹中的源文件中。源文件foo/f.go、foo/bar/x.go、foo/quux/y.go都可導入“foo/internal/baz”,但源文件crash/bang/b.go不可以。
細節參閱https://golang.org/s/go14internal。
vendor目錄
go 1.6包含使用外部依賴的本地副本的支持,以滿足那些依賴的導入,通常被稱為使用vendor(vendoring)。
在名為“vendor”目錄以下的代碼只可以被以“vendor”的父目錄為根的目錄樹中的代碼導入,並且只使用忽略直到並包括vendor元素前綴的導入路徑。
這是從上一小節來的例子,但“internal”目錄重命名為“vendor”並且添加了一個新的foo/vendor/crash/bang目錄:
/home/user/go/
src/
crash/
bang/ (bang包中的代碼)
b.go
foo/ (foo包中的代碼)
f.go
bar/ (bar包中的代碼)
x.go
vendor/
crash/
bang/ (bang包中的代碼)
b.go
baz/ (baz包中的代碼)
z.go
quux/ (main包中的代碼)
y.go
應用和internal相同的可見性規則,但在z.go中的代碼導入為“baz”,而不是“foo/vendor/baz”。
在源代碼樹中較深的vendor目錄中的代碼隱藏在較高目錄中的代碼。在以foo為根的子樹中“crash/bang”的導入解析為“foo/vendor/crash/bang”,而不是最頂層的“crash/bang”。
vendor目錄中的代碼不受導入路徑檢查的影響(參閱“go help importpath”)。
當“go get”檢出或更新git倉庫時,其現在也更新子模塊。
vendor目錄不影響第一次被“go get”檢出的新倉庫的位置:它們總是放置在主GOPATH中,從不在vendor子樹中。
細節參閱https://golang.org/s/go15vendor。
gopath-get主題——遺留的GOPATH的go get
go get [-d] [-f] [-t] [-u] [-v] [-fix] [-insecure] [build flags] [packages]
“go get”命令根據go命令運行在模塊感知模式還是遺留的GOPATH模式來改變行為。這里的幫助文本,即使在模塊感知模式也可作為“go help gopath-get”訪問,描述“go get”在遺留的GOPATH模式下的操作。
get下載由導入路徑指定名字的包,以及它們的依賴。然后安裝指定名字的包,類似“go install”。
標志:
- -d:在下載包之后停止;亦即,其令get不安裝包。
- -f:只在-u被設置時有效,強制get -u不驗證每個包都是從其導入路徑隱含的源代碼控制倉庫檢出。如果源代碼是源的本地fork分支這將會有用。
- -fix:在解析依賴和構建代碼之前在已下載的包上運行fix工具。
- -insecure:允許使用如HTTP等不安全的方案,從倉庫拉取以及解析自定義域名。謹慎使用。改標志被反對使用並將在go的未來版本中移除。應該改用GOINSECURE環境變量,因為其提供對哪個包可以使用不安全的方案檢索的控制。詳細信息參閱“go help environment”。
- -t:同時下載指定的包構建測試所需的包。
- -u:使用網絡來更新指定名字的包及其依賴。默認情況下,get使用網絡來檢出缺少的包但不會使用它來查找已存在包的更新。
- -v:啟用詳細的進度和調試輸出。
get也接受構建標志來控制安裝。參閱“go help build”。
當檢出一個新包時,get創建目標目錄GOPATH/src/
當檢出或更新包時,get查找匹配Go本地安裝版本的分支(branch)或標簽(tag)。最重要的規則是,如果本地安裝正在運行版本“go1”,get查找名字為“go1”的分支或標簽。如果沒有這樣的版本存在,其檢索包的默認分支。
當go get檢出或更新一個Git倉庫,其也會更新被該倉庫引用的任何git子模塊。
get從不檢出或更新在vendor目錄中存儲的代碼。
關於指定包的更多信息,參閱“go help packages”。
關於“go get”如何查找下載的源代碼的更多信息,參閱“go help importpath”。
這段文字描述當使用GOPATH來管理源代碼和依賴時get的行為。如果相反go命令運行在模塊感知模式,“go help get”的內容會不同,類似地,get的標志和行為的細節也會改變。參閱“go help modules”和“go help module-get”。
參閱:go build、go install、go clean。
goproxy主題——模塊代理協議
Go模塊代理是能響應特定格式URL的GET請求的任何web服務器。請求沒有查詢(query)參數,因此即使從固定文件系統(包括file://URL)提供服務的站點也能成為模塊代理。
GOPROXY上的協議的詳細信息,參閱https://golang.org/ref/mod#goproxy-protocol。
importpath主題——import路徑語法
導入路徑(參閱“go help packages”)表示存儲在本地文件系統的包。通常,導入路徑表示或者標准包(如“unicode/utf8”)或者在其中一個工作空間(譯注:其概念可參考 相對導入路徑 小節)找到的包(更多細節參閱:“go help gopath”)。
相對導入路徑
以./或../開頭的導入路徑稱為相對路徑。工具鏈以兩種方式支持相對導入路徑作為快捷方式。
第一種,相對路徑可以用作命令行上的速記。如果你工作在包含以“unicode”導入的代碼的目錄中並想為“unicode/utf8”運行測試,你可以輸入“go test ./utf8”而不需要指定完整的路徑。同樣地,在相反的情況下,“go test ..”將從“unicode/utf8”目錄測試“unicode”。相對模式也是允許的,如“go test ./...”用來測試所有子目錄。關於模式語法的詳細信息參閱“go help packages”。
第二種,如果你不是在工作空間中編譯Go程序,你可以在該程序import導入語句中使用相對路徑來引用附近同樣不在工作空間中的代碼。這更易於在通常的工作空間外試驗使用小型的多包程序,但這種程序不能用“go install”來安裝(沒有工作空間來安裝它們),因此每次它們被構建都會從頭開始重新構建。為了避免歧義,Go程序不可以在工作空間中使用相對導入路徑。
遠程導入路徑
某些導入路徑也描述了如何使用版本控制系統為包獲取源代碼。
一些常見的代碼托管站點有特定的語法:
Bitbucket (Git, Mercurial)
import "bitbucket.org/user/project"
import "bitbucket.org/user/project/sub/directory"
GitHub (Git)
import "github.com/user/project"
import "github.com/user/project/sub/directory"
Launchpad (Bazaar)
import "launchpad.net/project"
import "launchpad.net/project/series"
import "launchpad.net/project/series/sub/directory"
import "launchpad.net/~user/project/branch"
import "launchpad.net/~user/project/branch/sub/directory"
IBM DevOps Services (Git)
import "hub.jazz.net/git/user/project"
import "hub.jazz.net/git/user/project/sub/directory"
對於托管在其它服務器上的代碼,導入路徑或者用版本控制類型限定,或者go工具可以通過http/https動態地拉取該導入路徑並從HTML中的一個標簽發現代碼的所在。
要聲明代碼的位置,repository.vcs/path
格式的導入路徑指定給出的倉庫,可帶或不帶.vcs后綴(譯注:見支持的版本控制系統),來使用指定名字的版本控制系統,然后是該倉庫中的路徑。支持的版本控制系統為:
Bazaar .bzr
Fossil .fossil
Git .git
Mercurial .hg
Subversion .svn
例如,import "example.org/user/foo.hg"
表示在example.org/user/foo或foo.hg的Mercurial倉庫的根目錄,import "example.org/repo.git/foo/bar"
表示在example.org/repo或repo.git的Git倉庫的foo/bar目錄。
當版本控制系統支持多種協議時,在下載時每一種會輪流嘗試。例如,Git下載嘗試https://,然后git+ssh://。
默認情況下,下載限於已知的安全協議(例如https、ssh)。要為Git下載覆蓋該設置,可以設置GIT_ALLOW_PROTOCOL環境變量(更多細節參閱:“go help environment”)。
如果導入路徑不是已知的代碼托管站點且也缺少版本控制限定符,go工具嘗試通過https/http拉取導入路徑並在文檔的HTML中查找標簽。
meta標簽有如下格式(譯注:標簽中name="go-import"是固定的):
<meta name="go-import" content="import-prefix vcs repo-root">
import-prefix是和倉庫根對應的導入路徑。其必須為用“go get”抓取的包的前綴或完全匹配。如果其不是完全匹配,會對前綴生成另一個http請求來驗證標簽是匹配的。
meta標簽應該盡可能早地在文件中出現。特別地,其應該在任何原始的JavaScript或CSS之前出現,以避免迷惑go命令的受限的解析器。
vcs是“bzr”、“fossil”、“git”、“hg”、“svn”之一。
repo-root是包含方案但不包含.vcs限定符的版本控制系統的根。
例如,import "example.org/pkg/foo"
將導致以下請求:
https://example.org/pkg/foo?go-get=1 (首選的)
http://example.org/pkg/foo?go-get=1 (備選的,只與-insecure一起)
(譯注:假設該頁面的請求為https://example.org/exproj?go-get=1)如果該頁面包含meta標簽<meta name="go-import" content="example.org git https://code.org/r/p/exproj">
,go工具將驗證https://example.org/?go-get=1包含相同的meta標簽,並然后git clone https://code.org/r/p/exproj進GOPATH/src/example.org。
當使用GOPATH時,下載的包被寫入至在GOPATH環境變量中列出的第一個目錄。(參閱“go help gopath-get”和“go help gopath”。)
當使用模塊時,下載的包存儲在模塊緩存中。參閱https://golang.org/ref/mod#module-cache。
當使用模塊時,go-import meta標簽一個額外的變量會被識別,且勝於那些列出版本控制系統的變量。該變量使用“mod”作為內容值中的vcs,如同:
<meta name="go-import" content="example.org mod https://code.org/moduleproxy">
該標簽表示用以example.org開頭的路徑從URL為https://code.org/moduleproxy上可用的模塊代理拉取模塊。關於代理協議的詳細信息參閱https://golang.org/ref/mod#goproxy-protocol。
導入路徑檢查
當如上所述的自定義導入路徑功能重定向至已知的代碼托管站點時,每個結果包都有兩個可能的導入路徑,使用自定義域名或已知的托管站點。
如果package語句后立即跟着(在下一個新行之前)這兩種格式之一的注釋,則被稱為帶有“導入注釋”(import comment):
package math // import "path"
package math /* import "path" */
go命令會拒絕安裝帶有導入注釋的包,除非包是被導入注釋中的導入路徑引用的。用這種辦法,導入注釋讓包作者確保使用自定義導入路徑而不是指向底層代碼托管站點的直接路徑。
對在vendor目錄樹中找到的代碼導入路徑檢查是禁用的。這令拷貝代碼進vendor目錄樹中的備用位置而無需更新導入注釋成為可能。
當使用模塊時導入路徑檢查也是禁用的。導入路徑注釋被go.mod文件中的module語句所淘汰。
更多細節參閱https://golang.org/s/go14customimport。
module-auth主題——使用go.sum的模塊校驗
當go命令下載模塊zip文件或go.mod文件至模塊緩存中時,會計算一個加密哈希並將其與一個已知的值比較,來驗證自從首次下載以來文件沒有改變。已知的哈希存儲在模塊根目錄中命名為go.sum的文件中。根據GOSUMDB、GOPRIVATE和GONOSUMDB的值,哈希也可從校驗和數據庫下載。
詳細信息,參閱https://golang.org/ref/mod#authenticating。
module-get主題——模塊感知的go get
(譯注:該主題介紹使用模塊管理源代碼和依賴的行為,亦即 go get——添加依賴包至當前模塊並安裝之 小節的內容,使用GOPATH的行為描述於 gopath-get主題——遺留的GOPATH的go get 小節。)
modules主題——模塊,模塊版本,及更多
模塊是Go怎樣管理依賴。
一個模塊是一起發布、版本化和分發的包集合。模塊可以直接從版本控制倉庫或從模塊代理服務器下載。
關於模塊的一系列教程,參閱https://golang.org/doc/tutorial/create-module。
關於模塊的詳細參考,參閱https://golang.org/ref/mod。
默認情況下,go命令可從https://proxy.golang.org下載模塊。其可使用https://sum.golang.org上的校驗和數據庫校驗模塊。兩服務都由Google的Go團隊運營。這些服務的隱私政策分別可在https://proxy.golang.org/privacy和https://sum.golang.org/privacy得到。
go命令的下載行為可以使用GOPROXY、GOSUMDB、GOPRIVATE和其它環境變量配置。更多信息參閱“go help environment”和https://golang.org/ref/mod#private-module-privacy。
packages主題——包列表和模式
許多命令應用於一個包集合:
go action [packages]
通常,[packages]是導入路徑的列表。
為根路徑或以.或..元素開頭的導入路徑被解析為文件系統路徑並表示該目錄中的包。
否則,對某些在GOPATH環境變量中列出的DIR,導入路徑P表示DIR/src/P目錄中找到的包(更多詳細信息參閱:“go help gopath”)。
如果沒有給出導入路徑,操作應用於當前目錄中的包。
路徑有四個保留的名字,不應該用於使用go工具進行構建的包:
- “all”:擴展為所有GOPATH樹中找到的所有包。例如,“go list all”列出本地系統上的所有包。當使用模塊時,“all”擴展為主模塊及其依賴中的所有包,包括其中任何的測試所需的依賴。
- “cmd”:擴展為Go倉庫的命令及其內部庫。
- “main”:表示獨立的可執行文件中的頂層包。
- “std”:類似all但只擴展為標准Go庫中的包。
以“cmd/”開頭的導入路徑只匹配Go倉庫中的源代碼。
導入路徑是一個模式如果其包含一個或多個“...”通配符,其中每個都可以匹配任何字符串,包括空字符串和含斜杠的字符串。這樣的模式擴展為GOPATH樹中找到的名字匹配模式的所有包目錄。
為了令常見的模式更方便,有兩種特殊情況。第一種,模式末尾的/...可以匹配空字符串,因此net/...匹配net和在其子目錄中的包,如net/http。第二種,任何包含通配符的斜杠分隔的模式元素從不參與vendor包路徑中“vendor”元素的匹配,因此./...不匹配./vendor或./mycode/vendor的子目錄中包,但./vendor/...和./mycode/vendor/...可以。然而,注意,自身包含代碼的名字為vendor的目錄不是vendor的包:cmd/vendor可能是名字為vendor的命令,並且模式cmd/...匹配之。更多關於使用vendor的信息參閱golang.org/s/go15vendor。
導入路徑也可以命名要從遠程倉庫下載的包。詳細信息運行“go help importpath”。
程序中的每個包必須有唯一的導入路徑。按習慣,這通過使每個路徑以屬於你的唯一前綴開始來實現。例如,在Google內部使用的路徑都以“google”開頭,並且表示遠程倉庫的路徑以代碼的路徑開頭,例如“github.com/user/repo”。
程序中的包不必有唯一的包名,但有兩個有特殊含義的保留包名。名字main表示命令,而不是庫。命令會被構建為二進制且不能被導入。名字documentation表示目錄中非Go程序的文檔。documentation包中的文件會被go命令忽略。
作為特殊情況,如果包列表是單個目錄中的.go文件的列表,命令會被應用於恰好由那些文件構成的單個合成的包,忽略那些文件中的任何構建約束並忽略目錄中任何其它文件。
以“.”或“_”開頭的目錄和文件名會被go工具忽略,如同名字為“testdata”的目錄。
private主題——下載非公共代碼的配置
go命令默認從proxy.golang.org上的公共Go模塊鏡像下載模塊。無論來源是什么,其也默認將下載的模塊與sum.golang.org上的公共Go校驗和數據庫校驗。對公開可獲得的源代碼這些默認行為工作得很好。
GOPRIVATE環境變量控制哪些模塊go命令認為是私有的(不是公開可獲得的)並應該因此不使用代理或校驗和數據庫。變量是模塊路徑前綴的glob模式(以Go的path.Match的語法)的逗號分隔的列表。例如,
GOPRIVATE=*.corp.example.com,rsc.io/private
其令go命令將帶有匹配任一模式的路徑前綴的任何模塊視為私有,包括git.corp.example.com/xyzzy、rsc.io/private、rsc.io/private/quux。
為了對模塊下載和校驗進行細粒度的控制,GONOPROXY和GONOSUMDB接受相同類型的glob列表,並覆蓋GOPRIVATE以分別地對是否使用代理和校驗和數據庫作特定的決定。
例如,如果公司運行了一個為私有模塊服務的模塊代理,用戶可以如下使用來配置go:
GOPRIVATE=*.corp.example.com
GOPROXY=proxy.example.com
GONOPROXY=none
GOPRIVATE環境變量也被用來為GOVCS環境變量定義“public”和“private”模式;參閱“go help vcs”。對該用法,GOPRIVATE甚至應用於GOPATH模式中。在那種情況下,其匹配導入路徑而不是模塊路徑。
“go env -w”命令(參閱“go help env”)可以用來為未來的go命令調用設置這些環境變量。
更多詳細信息,參閱https://golang.org/ref/mod#private-modules。
testflag主題——測試標志
“go test”命令接受應用於“go test”自身的標志和應用於生成的測試二進制的標志。
標志中的幾個控制性能分析(profiling)並寫入適合“go tool pprof”的性能分析執行的文件;更多信息運行“go tool pprof -h”。pprof的--alloc_space、--alloc_objects、--show_bytes選項控制信息如何呈現。
以下的標志被“go test”命令識別並控制任何測試的執行:
(譯注:以下標志闡述中,測試(大多數)指test,基准測試指benchmark,范例指example;性能分析指profile。)
-
-bench regexp:只運行那些匹配正則表達式的基准測試。默認情況下,不運行基准測試。要運行所有基准測試,使用“-bench .”或“-bench=.”。正則表達式由無括號的斜杠(/)字符分隔為一系列正則表達式,且基准測試的標識符的每部分必須匹配序列中對應的元素,如果有的話。匹配項的可能的父項以b.N=1運行來標識子基准測試。例如,給定-bench=X/Y,頂層基准測試匹配X且以b.N=1運行來發現任何匹配Y的子基准測試,其是之后會全部運行的項。
-
-benchtime t:為每個基准測試運行足夠的迭代以消耗時間t,其被指定為time.Duration(例如,-benchtime 1h30s)。默認值為1秒(1s)。特殊的語法Nx表示運行基准測試N次(例如,-benchtime 100x)。
-
-count n:運行每個測試和基准測試n次(默認為1)。如果-cpu被設置,對每個GOMAXPROCS值(譯注:-cpu設置的列表中的每個值)運行n次。范例總是只運行一次。
-
-cover:啟用覆蓋率分析。注意因為覆蓋率分析通過在編譯前注解源代碼來工作,啟用覆蓋率分析的編譯和測試失敗可能報告和原來的源代碼不對應的行號。
-
-covermode set,count,atomic:設置對被測試的包的覆蓋率分析模式。默認為“set”除非-race被啟用,這種情況下為“atomic”。值為:
- set(bool):此語句是否運行?
- count(int):此語句運行多少次?
- atomic(int):計數,但在多線程測試中正確;明顯更高消耗。
會設置-cover。
-
-coverpkg pattern1,pattern2,pattern3:對匹配模式的包的每個測試應用覆蓋率分析。默認對每個測試只分析被測試的包。關於包模式的描述參閱“go help packages”。會設置-cover。
-
-cpu 1,2,4:指定GOMAXPROCS(譯注:runtime.GOMAXPROCS的返回值)值列表,測試或基准測試會以此來執行。默認為GOMAXPROCS的當前值。
-
-failfast:在首個測試失敗之后不再開始新的測試。
-
-list regexp:列出匹配正則表達式的測試、基准測試或范例。沒有測試、基准測試或范例會被運行。這只會列出頂層測試。沒有子測試或子基准測試會被展示。
-
-parallel n:允許調用t.Parallel的測試函數並行執行。這個標志的值是同時運行的測試的最大值;默認下,其設置為GOMAXPROCS的值。注意-parallel只應用於單個測試二進制中。根據-p標志的設置(參閱“go help build”),“go test”命令也可能為多個包並行運行測試。
-
-run regexp:只運行匹配正則表達式的那些測試和范例。對於測試,正則表達式由無括號的斜杠(/)字符分隔為一系列正則表達式,且測試的標識符的每部分必須匹配序列中對應的元素,如果有的話。注意匹配項的可能的父項也會運行,因此-run=X/Y匹配、運行、報告所有匹配X的測試的的結果,即使它們並沒有匹配Y的子測試,因為必須運行它們來查找那些子測試。
-
-short:告訴長時間運行的測試來縮短它們的運行時間。默認是關閉的,但在all.bash運行期間會設置,因此安裝Go樹可以運行健全的檢查但不會花費時間運行詳盡的測試。
-
-timeout d:如果測試二進制運行長於時長d,會panic。如果d是0,超時會被禁用。默認為10分鍾(10m)。
-
-v:詳細的輸出:在測試運行時記錄所有測試的日志。即使測試成功也會打印所有由Log和Logf調用產生的文本。
-
-vet list:配置“go test”運行期的“go vet”調用來使用vet檢查的逗號分隔的列表。如果列表為空,“go test”以一個精心設計的被認為總是值得提及的檢查列表運行“go vet”。如果列表為“off”,“go test”根本不會運行“go vet”。
以下標志也會被“go test”識別並能用來在執行期間對測試進行性能分析:
- -benchmem:為基准測試打印內存分配統計數據。
- -blockprofile block.out:當所有測試完成時寫入goroutine阻塞性能分析至指定的文件。會如同-c(譯注:go test的標志)那樣寫入測試二進制。
- -blockprofilerate n:通過使用n調用runtime.SetBlockProfileRate來控制在goroutine阻塞性能分析中提供的詳細信息。參閱“go doc runtime.SetBlockProfileRate”。性能分析器旨在程序花費於阻塞平均每n納秒采樣一次阻塞事件。默認情況下,如果-test.blockprofile(譯注:即-blockprofile標志)設置時不帶本標志,所有阻塞事件都會被記錄,等同於-test.blockprofilerate=1。
- -coverprofile cover.out:在所有測試通過后寫入覆蓋率性能分析至文件。會設置-cover。
- -cpuprofile cpu.out:在退出前寫入CPU性能分析至指定的文件。會如同-c那樣寫入測試二進制。
- -memprofile mem.out:在所有測試通過后寫入內存分配性能分析至文件。會如同-c那樣寫入測試二進制。
- -memprofilerate n:通過設置runtime.MemProfileRate啟用更多精確的(並昂貴的)內存分配性能分析。參閱“go doc runtime.MemProfileRate”。要對所有內存分配進行性能分析,使用-test.memprofilerate=1。
- -mutexprofile mutex.out:當所有測試完成時寫入互斥鎖爭用性能分析至指定的文件。會如同-c那樣寫入測試二進制。
- -mutexprofilefraction n:采樣n個持有爭用互斥鎖的goroutine堆棧跟蹤信息中的1個。
- -outputdir directory:將性能分析的輸出文件放置於指定的目錄中,默認為“go test”運行的目錄中。
- -trace trace.out:在退出前寫入執行跟蹤信息至指定的文件。
這些標志的每個也能以可選的“test.”前綴被識別,如同-test.v。然而,當直接調用生成的測試二進制時(“go test -c”的結果),前綴是強制的。
視情況而定,在調用測試二進制之前,“go test”命令重寫或移除在可選的包列表之前和之后的已識別的標志。
例如,命令go test -v -myflag testdata -cpuprofile=prof.out -x
將編譯測試二進制並以pkg.test -test.v -myflag testdata -test.cpuprofile=prof.out
運行(-x標志被移除因為其只應用於go命令的執行,而非測試自身)。
生成性能分析的測試標志(除了用於覆蓋率的)也保留測試二進制在pkg.test中以在分析性能分析結果時使用。
當“go test”運行測試二進制時,其會在對應的包源代碼目錄內運行。根據測試的不同,當直接調用生成的測試二進制時可能需要做同樣的事情。
命令行包列表,如果存在,必須出現在任何go test命令不認識的標志之前。繼續上面的例子,包列表本應出現在-myflag之前,但可以出現在-v的任一側。
當“go test”運行在包列表模式時,“go test”緩存成功的包測試結果來避免測試的不必要重復運行。要禁用測試緩存,使用除可緩存標志以外的任意測試標志或參數。顯式地禁用測試緩存的習慣方式為使用-count=1。
要避免測試二進制的參數被解析為已知的標志或包名,使用-args(參閱“go help test”),其將命令行中余下部分不解析和不修改地傳遞至測試二進制。
例如,命令go test -v -args -x -v
將編譯測試二進制並以pkg.test -test.v -x -v
運行。類似地,go test -args math
將編譯測試二進制並以pkg.test math
運行。
在第一個例子中,-x和第二個-v不修改地傳遞至測試二進制且對go命令自身沒有影響。在第二個例子中,參數math傳遞至測試二進制,而不是被解析為包列表。
testfunc主題——測試函數
“go test”命令期望在與被測試的包對應的“*_test.go”文件中找到測試、基准測試和范例函數。
測試函數是一個名為TestXxx(Xxx處不以小寫字母開頭)且應具有特征:
func TestXxx(t *testing.T) { ... }
基准測試函數是一個名為BenchmarkXxx且應具有特征:
func BenchmarkXxx(b *testing.B) { ... }
范例函數類似於測試函數,但取代使用*testing.T來報告成功或失敗,會打印輸出至os.Stdout。如果函數中的最后的注釋以“Output:”開頭,那么輸出會精確地與注釋比較(參閱下面的例子)。如果最后的注釋以“Unordered output:”開頭,那么輸出與注釋比較,但是忽略行的順序。沒有如此注釋的范例會被編譯但不會被執行。“Output:”后沒有文本的范例會被編譯、執行並期望不產生輸出。
godoc展示ExampleXxx的函數體來示范函數、常量或變量Xxx的使用。接收類型T或*T的方法M的范例命名為ExampleT_M。對給定的函數、常量或變量可能有多個范例,以尾隨的_xxx區分,xxx是不以大寫字母開頭的后綴。
這是范例的例子:
func ExamplePrintln() {
Println("The output of\nthis example.")
// Output: The output of
// this example.
}
這是忽略輸出順序的另一個例子:
func ExamplePerm() {
for _, value := range Perm(4) {
fmt.Println(value)
}
// Unordered output: 4
// 2
// 1
// 3
// 0
}
整個測試文件會作為范例展示,當其包含單個范例函數,至少一個其它函數、類型、變量或常量聲明,沒有測試或基准測試函數時。
更多信息參閱testing包的文檔。
vcs主題——用GOVCS控制版本控制
“go get”命令能運行類似git的版本控制命令來下載被導入的代碼。這個功能對分散的Go包生態系統是極重要的,在其中代碼可以從任何服務器導入,但其也是個潛在的安全問題,如果一個惡意的服務器找到導致被調用的版本控制命令運行未預期代碼的方法。
為了平衡功能和安全憂慮,“go get”命令默認將只使用git和hg來從公共服務器下載代碼。但其將使用任何已知的版本控制系統(bzr、fossil、git、hg、svn)來從私有服務器——定義為匹配GOPRIVATE環境變量(參閱“go help private”)的那些托管的包——下載代碼。只允許Git和Mercurial背后的根本原因是這兩個系統最關注作為不可信服務器的客戶端運行的問題。相比之下,Bazaar、Fossil和Subversion主要被用於可信的、已認證的環境且沒有如同受攻擊面那樣很好地被仔細檢查。
版本控制命令限制只應用於當使用直接的版本控制訪問來下載代碼時。當從代理下載模塊時,“go get”改用代理協議,其總是被允許的。默認情況下,“go get”命令為公共包使用Go模塊鏡像(proxy.golang.org),且只當為私有包或當鏡像拒絕為公共包服務(典型地為法律原因)時才退回至版本控制。因此,默認情況下客戶端仍然能訪問從Bazaar、Fossil或Subversion倉庫提供的公共代碼,因為那些下載使用Go模塊鏡像,其使用自定義沙箱承擔了運行版本控制命令的安全風險。
GOVCS環境變量能用來為特定的包(由模塊或導入路徑標記)改變允許的版本控制系統。當在模塊感知模式和GOPATH模式下構建包時,GOVCS環境變量都會應用。當使用模塊時,模式與模塊路徑匹配。當使用GOAPTH時,模式與對應於版本控制倉庫的根的導入路徑匹配。
GOVCS設置的一般形式為pattern:vcslist規則的逗號分隔的列表。pattern是必需匹配一個或多個模塊或導入路徑的前導元素的glob模式。vcslist是允許的版本控制命令的管道符分隔的列表,或“all”來允許使用任意已知的命令,或“off”來禁止所有命令。注意如果模塊匹配vcslist為“off”的模式,其仍可被下載,如果源服務器使用“mod”方案,其指示go命令使用GOPROXY協議下載模塊。應用列表中最先匹配的模式,即使后面的模式也可以匹配。
例如,考慮:
GOVCS=github.com:git,evil.com:off,*:git|hg
以此設置,以github.com/開頭的模塊或導入路徑的代碼只可以使用git;evil.com上的路徑不可以使用任何版本控制命令,且所有其它路徑(*匹配一切)只可以使用git或hg。
特殊的模式“public”和“private”匹配公共的和私有的模塊或導入路徑。路徑是私有的,如果其匹配GOPRIVATE環境變量;否則其是公共的。
如果GOVCS環境變量中沒有規則匹配一個特定的模塊或導入路徑,“go get”命令應用其默認規則,即現可被概括為GOVCS中的表示法“public:git|hg,private:all”。
要允許為任何包任何版本控制系統的無限制的使用,使用:
GOVCS=*:all
要禁止版本控制的所有使用,使用:
GOVCS=*:off
“go env -w”命令(參閱“go help env”)可以用來為未來的go命令調用設置GOVCS環境變量。