天天看點

Go語言從入門到規範-7.1、Go語言指令Go語言從入門到規範-7.1、Go語言指令

Go語言從入門到規範-7.1、Go語言指令

文章目錄

  • Go語言從入門到規範-7.1、Go語言指令
    • 1. 前言
    • 2. 指令簡介
    • 3. go指令
    • 4. 編譯包和依賴項build
    • 5. 删除目标檔案
    • 6. 列印Go環境資訊
    • 7. 在包上運作go工具fix
    • 8. 在package sources上運作gofmt
    • 9. 通過處理源代碼生成Go檔案
    • 10. 下載下傳并安裝軟體包和依賴項
    • 11. 編譯和安裝軟體包和依賴項
    • 12. 列出套件包
    • 13. 編譯并運作Go程式
    • 14. 測試包
    • 15. 運作指定的go工具
    • 16. 列印Go版本
    • 17. 在軟體包上運作go工具vet
    • 18. 在Go和C之間調用
    • 19. 檔案類型
    • 20. GOPATH環境變量
    • 21. 導入路徑文法
    • 22. 相對導入路徑
    • 23. 遠端導入路徑
    • 24. 檢查導入路徑
    • 25. package lists說明
    • 25. 測試标志說明
    • 26. 測試功能說明

1. 前言

正是由于指令的存在,使得Go在某些情況下像是python等語言一樣解釋執行,實際上Go的指令确實吸收了解釋器的優點,使得一些常見系統的交叉編譯更加友善(雖然失去了部分自由性,但是仍然可自行擴充适配),然後又将編譯語言所需要的編譯、連結等過程封裝指令化,不同平台等都是一套指令,而當有新的需求後,支撐指令的程式也可以随着Go更新而更新,使得Go兼具解釋性語言和編譯型語言的特性。

2. 指令簡介

這是一組用來建構并處理 Go 源碼的程式套件。本套件中的程式并不直接運作,而是通過 go 程式來調用。

運作這些程式最普通的方式就是作為 go 程式的子指令,例如 go fmt。若像這樣運作, 該指令就會在Go源碼的完整包上進行操作,它使用 go 程式通過适當的實參來調用基本的二進制程式以進行包級處理。

也可作為獨立的二進制程式,加上未修改的實參,并使用 go 的 tool 子指令來運作,例如 go tool vet。以下調用風格也是允許的,例如, 檢查單個源檔案而非整個包:go tool vet myprogram.go 對比于 go vet mypackage。 有一些指令,如 yacc,隻能通過 go 的 tool 子指令來通路。

最後,fmt 與 doc 兩個指令也作為正常的二進制被安裝為 gofmt 和 godoc,因為它們偶爾會被引用。

欲擷取更多文檔、調用方法及用法詳述,請點選以下連結。

名稱 簡介
go

go

程式管理 Go 源碼以及運作其它在此列出的指令。用法詳述見指令文檔。
cgo Cgo 使 Go 包的建立能夠調用 C 代碼。
cover Cover 用于建立并優化由

"go test -coverprofile"

生成的規模評估。
fix Fix 發現使用舊語言與庫特性的 Go 程式,并使用較新的特性來重寫它們。
fmt Fmt 格式化 Go 包,它作為獨立的gofmt指令,使用更一般的選項同樣有效。
godoc Godoc 從 Go 包中提取并生成文檔。
vet Vet 檢查 Go 源碼并報告可疑的構造,例如 Printf 調用的實參數與格式化字元串不比對。
yacc Yacc 是 yacc 的一個版本,它生成在 Go 中實作的解析器。

這是一個簡略的清單。編譯器及更多文檔見完整的指令參考

3. go指令

Go是一個管理Go源代碼的工具。

用法:

go指令包括:

build   編譯包和依賴項
clean   删除目标檔案
env     列印Go環境資訊
fix     在包上運作go工具修複
gofmt   在包源碼上運作gofmt
get     下載下傳并安裝軟體包和依賴項
install 編譯和安裝軟體包和依賴項
list    列出全部擴充
run     編譯并運作Go程式
test    測試包
tool    運作指定的go工具
version 列印Go版本
vet     在軟體包上運作Go工具vet
           

使用“go help [command]”擷取指令的更多資訊。

額外的幫助主題:

c           在Go和c之間調用
filetype    檔案系統
gopath      GOPATH環境變量
importpath  導入路徑語言
packages    包清單說明
teslflag    測試标志說明
testfunc    測試功能說明
           

使用“go help [topic]”來擷取關于該話題的更多資訊。

4. 編譯包和依賴項build

用法:

Build編譯以導入路徑命名的包及其依賴項,但不安裝結果。

如果參數是.go檔案的清單,build将它們視為指定單個包的源檔案清單。

當指令行指定單個主包時,build将生成的可執行檔案寫入輸出。否則,build會編譯包,但會丢棄結果,隻用于檢查是否可以建構包。

-o标志指定輸出檔案名。如果沒有指定,輸出檔案名依賴于參數并派生于包的名稱,如p.a表示包p,除非p是’main’。如果包是main并且提供了檔案名,則檔案名派生于提到的第一個檔案名,例如f1表示’go build f1.go f2.go”;如果沒有提供檔案(‘go build’),輸出檔案名就是包含目錄的基本名稱。

-i标志安裝與目标相關的包。

建構flags由build、clean、get、install、list、run和test指令共享:

-a
    強制重新建構已經更新的包。
    在Go版本中,不适用于标準庫。
-n
    列印指令但不運作它們。
-p n
    可以并行運作的建構的數量。
    預設值是可用的cpu數量。
-race
    啟用資料競争檢測。
    僅支援linux/amd64, freebsd/amd64, darwin/amd64和windows/amd64。
-v
    在編譯包時列印包名。
-work
    列印臨時工作目錄的名稱和退出時不要删除。
-x
    列印指令
-ccflags 'arg list'
    每個5c、6c或8c編譯器調用傳遞的參數。
-compiler name
    要使用的編譯器名稱,如在運作時。編譯器(gccgo或gc)。
-gccgoflags 'arg list'
    參數傳遞給每個gccgo編譯器/連結器調用。
-gcflags 'arg list'
    每個5g、6g或8g編譯器調用傳遞的參數。
-installsuffix suffix
    用于包安裝目錄名稱的字尾,為了使輸出與預設建構分開。
    如果使用-race标志,安裝字尾将自動設定為race
或者,如果顯式設定,則附加有_race。
-ldflags 'flag list'
    參數傳遞給每個5l、6l或8l連結器調用。
-tags 'tag list'
    建構過程中要考慮的建構标記清單。
    有關建構标記的更多資訊,請參見在go/ Build包的文檔中建構限制。
           

清單标志接受空格分隔的字元串清單。若要在清單中的元素中嵌入空格,請用單引号或雙引号将其包圍。

有關指定包的更多資訊,請參見“去幫助包”。有關安裝包和二進制檔案的更多資訊,請運作’go help gopath’。關于Go和C/c++之間調用的更多資訊,運作’ Go help C '。

參見:go install, go get,go clean

5. 删除目标檔案

用法:

Clean從包源目錄中删除目标檔案。go指令在臨時目錄中建構大多數對象,是以go clean主要關注其他工具或手動調用go build留下的對象檔案。

具體來說,clean将從與導入路徑對應的每個源目錄中删除以下檔案:

_obj/            舊的對象檔案,makefile産生
_test/           舊的測試檔案, Makefiles産生
_testmain.go     舊的gotest檔案, Makefiles産生
test.out         舊的測試log, Makefiles産生
build.out        舊的測試log, Makefiles産生
*.[568ao]        對象檔案, Makefiles産生

DIR(.exe)        go build産生
DIR.test(.exe)   go test -c産生
MAINFILE(.exe)   go build MAINFILE.go産生
*.so             SWIG産生
           

在清單中,DIR表示目錄的最終路徑元素,而MAINFILE是在建構包時未包含的目錄中任何Go源檔案的基本名稱。

-i标志導緻clean删除相應的已安裝的歸檔檔案或二進制檔案('go install’将建立的檔案)。

-n标志導緻clean列印它将執行的删除指令,但不會運作它們。

-r标志導緻clean被遞歸應用到由導入路徑命名的包的所有依賴項。

-x标志導緻clean在執行删除指令時列印它們。

有關建構标志的更多資訊,請參閱’go help build’。

有關指定包的更多資訊,請參見“go help packages”。

6. 列印Go環境資訊

用法:

Env列印Go環境資訊。

預設情況下,env将資訊列印為shell腳本(在Windows上是批處理檔案)。如果給出一個或多個變量名作為參數,env将每個已命名變量的值列印在該行上。

7. 在包上運作go工具fix

用法:

Fix對以導入路徑命名的包運作Go Fix指令。

有關修複的更多資訊,請參見“godoc修複”。有關指定包的更多資訊,請參見“去幫助包”。

要運作特定選項的fix,請運作’go tool fix’。

參見:go fmt,go vet。

8. 在package sources上運作gofmt

用法:

Fmt對以導入路徑命名的包運作’gofmt -l -w’指令。它列印被修改的檔案的名稱。

有關gofmt的更多資訊,請參見“godoc gofmt”。有關指定包的更多資訊,請參見“go help packages”。

-n标志列印将要執行的指令。-x标志在執行指令時列印指令。

要運作帶有特定選項的gofmt,請運作gofmt本身。

參見:go fix,go vet。

9. 通過處理源代碼生成Go檔案

用法:

生成由現有檔案中的指令描述的運作指令。這些指令可以運作任何程序,但目的是建立或更新Go源檔案,例如通過運作yacc。

Go generate不會通過Go build, Go get, Go test等方式自動運作。它必須顯式地運作。

Go generate掃描檔案中的指令,這些指令是表格中的行,

//go:generate command argument...
           

(注意:“//go”中沒有空格和前導空格)這裡的指令是要運作的生成器,對應于一個可以在本地運作的可執行檔案。它必須在shell路徑(gofmt),一個完全限定的路徑(/usr/you/bin/mytool),或者一個指令别名,如下所述。

請注意,go generate并不解析檔案,是以看起來像注釋中的指令或多行字元串的行将被視為指令。

指令的參數是空格分隔的标記或雙引号字元串,在運作時作為單獨的參數傳遞給生成器。

引用字元串使用

$GOARCH     執行架構(arm、amd64等)
$GOOS       執行作業系統(linux、windows等)
$GOFILE     檔案的基本名稱。
$GOPACKAGE  包含該指令的檔案的包名。 
           

除了變量替換和帶引号的字元串計算外,在指令行上不執行“globbing”之類的特殊處理。

作為運作該指令之前的最後一步,對任何具有字母數字名稱(例如 G O F I L E 或 GOFILE或 GOFILE或HOME)的環境變量的任何調用都将在整個指令行中展開。變量展開的文法在所有作業系統上都是$NAME。由于求值的順序,變量甚至在帶引号的字元串中進行擴充。如果沒有設定變量NAME,$NAME擴充為空字元串。

一種形式的指令,

//go:generate -command xxx args...
           

對于源檔案的其餘部分,指定字元串XXX表示由參數辨別的指令。這可用于建立别名或處理多字生成器。例如,

//go:generate -command yacc go tool yacc
           

指定指令“yacc”代表生成器“go tool yacc”。

按照指令行上給出的順序,一次生成一個程序包。如果指令行列出.go檔案,則将它們視為單個包。在包中,generate按照檔案名的順序處理包中的源檔案,一次一個。在源檔案中,generate按照生成器在檔案中出現的順序運作生成器,每次一個。

如果任何生成器傳回錯誤退出狀态,“go generate”将跳過該包的所有進一步處理。

生成器在包的源目錄中運作。

Go generate接受一個特定的标志:

-run=""
    if non-empty, specifies a regular expression to
    select directives whose command matches the expression.
           

它還接受标準的建構标志-v、-n和-x。-v标志在處理包和檔案時列印包和檔案的名稱。-n标志列印将要執行的指令。-x标志在執行指令時列印指令。

有關指定包的更多資訊,請參見“go help packages”。

10. 下載下傳并安裝軟體包和依賴項

用法:

Get下載下傳并安裝按導入路徑命名的包及其依賴項。

-d标志訓示下載下傳包後停止;也就是說,它訓示get不要安裝軟體包。

-f标志僅在-u設定時有效,它強制get -u不驗證每個包是否已從其導入路徑所暗示的源代碼控制存儲庫簽出。如果源檔案是原始檔案的本地分支,這将非常有用。

-fix标志訓示在解析依賴項或建構代碼之前,對下載下傳的包運作修複工具。

-t标志還訓示下載下傳為指定的包建構測試所需的包。

u标志訓示使用網絡更新已命名包及其依賴項。預設情況下,get使用網絡檢出丢失的包,但不使用它查找現有包的更新。

Get還接受建構标志來控制安裝。參見“go help build”。

簽出或更新包時,get會查找與本地安裝的Go版本相比對的分支或标記。最重要的規則是,如果本地安裝運作的版本是“go1”,搜尋名為“go1”的分支或标記。如果不存在這樣的版本,它将檢索包的最新版本。

有關指定包的更多資訊,請參見“go help packages”。

有關’go get’如何找到要下載下傳的源代碼的更多資訊,請參見’go help importpath’。

參見:go build,go install,go clean。

11. 編譯和安裝軟體包和依賴項

用法:

Install編譯并安裝由導入路徑命名的包及其依賴項。

有關建構标志的更多資訊,請參閱’go help build’。有關指定包的更多資訊,請參見“去幫助包”。

也可以看到:go build,go get,go clean。

12. 列出套件包

用法:

List列出了按導入路徑命名的包,每行一個。

預設輸出顯示包導入路徑:

code.google.com/p/google-api-go-client/books/v1
code.google.com/p/goauth2/oauth
code.google.com/p/sqlite
           

-f标志使用包模闆的文法為清單指定了一種替代格式。預設輸出相當于-f ‘{{. importpath}}’。傳遞給模闆的結構體是:

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
    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?
    Root          string // Go root or Go path dir containing this package

    // Source files
    GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
    CgoFiles       []string // .go sources files that import "C"
    IgnoredGoFiles []string // .go sources 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
    SFiles         []string // .s source files
    SwigFiles      []string // .swig files
    SwigCXXFiles   []string // .swigcxx files
    SysoFiles      []string // .syso object files to add to archive

    // Cgo directives
    CgoCFLAGS    []string // cgo: flags for C compiler
    CgoCPPFLAGS  []string // cgo: flags for C preprocessor
    CgoCXXFLAGS  []string // cgo: flags for C++ compiler
    CgoLDFLAGS   []string // cgo: flags for linker
    CgoPkgConfig []string // cgo: pkg-config names

    // Dependency information
    Imports []string // import paths used by this package
    Deps    []string // all (recursively) imported dependencies

    // Error information
    Incomplete bool            // this package or a dependency has an error
    Error      *PackageError   // error loading package
    DepsErrors []*PackageError // errors loading dependencies

    TestGoFiles  []string // _test.go files in package
    TestImports  []string // imports from TestGoFiles
    XTestGoFiles []string // _test.go files outside package
    XTestImports []string // imports from XTestGoFiles
}
           

模闆函數“join”調用strings.Join。

模闆函數"context"傳回建構上下文,定義如下:

type Context struct {
    GOARCH        string   // target architecture
    GOOS          string   // target operating system
    GOROOT        string   // Go root
    GOPATH        string   // Go path
    CgoEnabled    bool     // whether cgo can be used
    UseAllFiles   bool     // use files regardless of +build lines, file names
    Compiler      string   // compiler to assume when computing target paths
    BuildTags     []string // build constraints to match in +build lines
    ReleaseTags   []string // releases the current release is compatible with
    InstallSuffix string   // suffix to use in the name of the install dir
}
           

有關這些字段含義的更多資訊,請參見go/build包的Context類型的文檔。

-json标志導緻包資料以JSON格式列印,而不是使用模闆格式。

-e标志更改錯誤包的處理,即無法找到或格式不正确的包。預設情況下,list指令為每個錯誤包列印一個錯誤到标準錯誤,并在通常列印過程中忽略這些包。使用-e标志,list指令不會将錯誤列印到标準錯誤,而是使用通常的列印處理錯誤包。錯誤的包将有一個非空的ImportPath和一個非空的Error字段;其他資訊可能丢失,也可能不丢失(歸零)。

有關建構标志的更多資訊,請參閱’go help build’。

有關指定包的更多資訊,請參見“go help packages”。

13. 編譯并運作Go程式

用法:

Run編譯并運作包含Go源檔案的主包。Go源檔案被定義為以".go”字尾的檔案。

預設情況下,'go run’直接運作編譯後的二進制檔案:‘a.out arguments…’。如果給出了-exec标志,'go run’将使用xprog: 'xprog a.o narguments…'調用二進制檔案。如果沒有給出-exec标志,GOOS或GOARCH與系統預設值不同,并且在目前搜尋路徑上可以找到一個名為go_KaTeX parse error: Expected group after '_' at position 5: GOOS_̲GOARCH_exec的程式,‘go run’使用該程式調用二進制檔案,例如’go_nacl_386_exec a.out arguments…’。這允許在模拟器或其他執行方法可用時執行交叉編譯的程式。

有關建構标志的更多資訊,請參閱’go help build’。

參見:go build

14. 測試包

用法:

'Go test’自動測試由導入路徑命名的包。它以如下格式輸出測試結果的摘要:

ok   archive/tar   0.011s
FAIL archive/zip   0.022s
ok   compress/gzip 0.033s
...
           

然後是每個失敗包的詳細輸出。

‘Go test’會重新編譯每個包,以及任何檔案名比對檔案模式"*test.go"的檔案。檔案名以“”(包括“_test.go”)或“。”開頭的檔案将被忽略。這些附加檔案可以包含測試函數、基準函數和示例函數。更多資訊請參見’go help testfunc’。每個列出的包都會導緻執行一個單獨的測試二進制檔案。

聲明帶有字尾“_test”的包的測試檔案将被編譯為一個單獨的包,然後與主測試二進制檔案連結并運作。

預設情況下,go測試不需要參數。它編譯和測試目前目錄中的源代碼包(包括測試),并運作測試。

該包建構在一個臨時目錄中,是以它不會幹擾非測試安裝。

除了建構标志,'go test’本身處理的标志是:

-c
    Compile the test binary to pkg.test but do not run it
    (where pkg is the last element of the package's import path).
    The file name can be changed with the -o flag.

-exec xprog
    Run the test binary using xprog. The behavior is the same as
    in 'go run'. See 'go help run' for details.

-i
    Install packages that are dependencies of the test.
    Do not run the test.

-o file
    Compile the test binary to the named file.
    The test still runs (unless -c or -i is specified).
           

測試二進制檔案也接受控制測試執行的标志;這些标記也可以通過“go test”通路。詳情請參閱’go help testflag’。

如果測試二進制檔案需要任何其他标志,它們應該顯示在包名之後。go工具将第一個以負号開頭的參數視為一個标志,它不能識别自己;該參數和所有後續參數都作為參數傳遞給測試二進制檔案。

有關建構标志的更多資訊,請參閱’go help build’。有關指定包的更多資訊,請參見“go help packages”。

參見:go build,go vet

15. 運作指定的go工具

用法:

工具運作由參數辨別的go工具指令。如果沒有參數,它将列印已知工具的清單。

-n标志導緻工具列印将要執行的指令,但不執行它。

有關每個工具指令的更多資訊,請參見“go tool command -h”。

16. 列印Go版本

go version
           

Version列印由runtime.Version報告的Go版本。

17. 在軟體包上運作go工具vet

用法:

Vet對以導入路徑命名的包運作Go Vet指令。

更多關于vet的資訊,請參見“godoc golang.org/x/tools/cmd/vet”。有關指定包的更多資訊,請參見“去go help packages”。

要運作帶有特定選項的vet工具,請運作’go tool vet’。

-n标志列印将要執行的指令。-x标志在執行指令時列印指令。

參見:go fmt, go fix。

18. 在Go和C之間調用

在Go和C/ c++代碼之間有兩種不同的調用方式。

第一個是cgo工具,它是Go發行版的一部分。有關如何使用它的資訊,請參閱cgo文檔(godoc 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++編譯器。

19. 檔案類型

go指令檢查每個目錄中受限制的檔案集的内容。它根據檔案名的擴充名識别要檢查的檔案。這些擴充是:

.go
    Go source files.
.c, .h
    C source files.
    If the package uses cgo, these will be compiled with the
    OS-native compiler (typically gcc); otherwise they will be
    compiled with the Go-specific support compiler,
    5c, 6c, or 8c, etc. as appropriate.
.cc, .cpp, .cxx, .hh, .hpp, .hxx
    C++ source files. Only useful with cgo or SWIG, and always
    compiled with the OS-native compiler.
.m
    Objective-C source files. Only useful with cgo, and always
    compiled with the OS-native compiler.
.s, .S
    Assembler source files.
    If the package uses cgo, these will be assembled with the
    OS-native assembler (typically gcc (sic)); otherwise they
    will be assembled with the Go-specific support assembler,
    5a, 6a, or 8a, etc., as appropriate.
.swig, .swigcxx
    SWIG definition files.
.syso
    System object files.
           

除了.syso之外,每種類型的檔案都可能包含建構限制,但go指令會在檔案中第一個非空行或//風格行注釋項停止掃描建構限制。

20. GOPATH環境變量

Go路徑用于解析導入語句。它是由go/build包實作并記錄的。

GOPATH環境變量列出了尋找Go代碼的地方。在Unix上,該值是冒号分隔的字元串。在Windows上,該值是一個分号分隔的字元串。在計劃9中,值是一個清單。

必須将GOPATH設定為擷取、建構和安裝标準Go樹之外的包。

GOPATH中列出的每個目錄必須有一個規定的結構:

src/目錄儲存源代碼。'src’下面的路徑決定了導入路徑或可執行檔案名。

pkg/目錄包含已安裝的包對象。和Go樹一樣,每個目标作業系統和體系結構對都有自己的pkg (pkg/GOOS_GOARCH)子目錄。

如果DIR是GOPATH中列出的目錄,那麼在DIR/src/foo/bar中包含source的包可以被導入為"foo/bar",并将其編譯後的形式安裝到"DIR/pkg/GOOS_GOARCH/foo/bar.a"中。

bin/目錄儲存已編譯的指令。每個指令都以其源目錄命名,但僅以最終元素命名,而不是以整個路徑命名。也就是說,在DIR/src/foo/quux中帶有source的指令被安裝到DIR/bin/quux中,而不是DIR/bin/foo/quux。foo/被剝離,以便您可以将DIR/bin添加到您的PATH以獲得已安裝的指令。如果設定了GOBIN環境變量,指令會安裝到它所指定的目錄下,而不是DIR/bin。

下面是一個目錄布局的示例:

GOPATH=/home/user/gocode

/home/user/gocode/
    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)
           

Go搜尋GOPATH中列出的每個目錄以找到源代碼,但是新的包總是被下載下傳到清單中的第一個目錄中。

21. 導入路徑文法

導入路徑(參見’go help packages’)表示存儲在本地檔案系統中的包。通常,導入路徑表示一個标準包(如"unicode/utf8")或在某個工作空間中找到的包(參見’go help gopath’)。

22. 相對導入路徑

以./或…開頭的導入路徑。/稱為相對路徑。工具鍊以兩種方式支援相對導入路徑。

首先,相對路徑可以用作指令行上的簡寫。如果您在包含以"unicode"導入的代碼的目錄下工作,并且想要運作"unicode/utf8"的測試,您可以鍵入"go test ./utf8",而不需要指定完整路徑。類似地,在相反的情況下,"go test …“将從"unicode/utf8"目錄中測試"unicode”。也允許使用相對模式,如“go test ./…”來測試所有子目錄。有關模式文法的詳細資訊,請參閱’go help packages’。

其次,如果正在編譯不在工作空間中的Go程式,可以在該程式的import語句中使用相對路徑來引用附近也不在工作空間中的代碼。這使得在通常的工作空間之外使用小的多包程式很容易,但是這樣的程式不能通過“go install”(沒有工作空間可以安裝它們)來安裝,是以每次建構它們時都要從頭開始重新建構。為了避免歧義,Go程式不能在工作空間内使用相對導入路徑。

23. 遠端導入路徑

某些導入路徑還描述了如何使用修訂控制系統擷取包的源代碼。

一些公共代碼托管網站有特殊的文法:

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"

Google Code Project Hosting (Git, Mercurial, Subversion)

    import "code.google.com/p/project"
    import "code.google.com/p/project/sub/directory"

    import "code.google.com/p/project.subrepository"
    import "code.google.com/p/project.subrepository/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工具可以通過https/http動态擷取導入路徑,并從HTML中的<meta>标記中發現代碼所在的位置。

要聲明代碼位置,請使用表單的導入路徑

repository.vcs/path
           

使用命名的版本控制系統指定給定的存儲庫(帶或不帶.vcs字尾),然後是存儲庫中的路徑。支援的版本控制系統有:

Bazaar      .bzr
Git         .git
Mercurial   .hg
Subversion  .svn
           

舉個例子:

表示Mercurial存儲庫example.org/user/foo或foo.hg和

表示Git倉庫的foo/bar目錄example.org/repo或repo.git。

當版本控制系統支援多種協定時,在下載下傳時依次嘗試每種協定。例如,Git下載下傳嘗試Git://,然後是"https://",然後是http://.

如果導入路徑不是一個已知的代碼托管站點,也沒有版本控制限定符,那麼go工具會嘗試通過https/http擷取導入,并在文檔的HTML <head>中查找<meta>标記。

meta标簽的形式如下:

import-prefix是與存儲庫根對應的導入路徑。它必須是一個字首或與“go get”擷取的包的精确比對。如果不是完全比對,則在字首處發出另一個http請求來驗證<meta>标記比對。

vcs是“git”、“hg”、“svn”等,

repo-root是版本控制系統的根,它包含一個方案,不包含.vcs限定符。

例如,

會引緻下列request:

https://example.org/pkg/foo?go-get=1 (preferred)
http://example.org/pkg/foo?go-get=1  (fallback)
           

如果該頁面包含元标記

go工具将驗證https://example.org/?go-get=1包含相同的元标簽,然後git克隆https://code.org/r/p/exproj到GOPATH/src/example.org。

新下載下傳的包被寫到GOPATH環境變量中列出的第一個目錄中(參見’go help GOPATH ')。

go指令嘗試下載下傳适合所使用的go版本的軟體包版本。Run “go help get” for more。

24. 檢查導入路徑

當上面描述的自定義導入路徑特性重定向到已知代碼托管站點時,每個生成的包都有兩個可能的導入路徑,分别使用自定義域或已知托管站點。

如果一個包語句後面(在下一個換行符之前)緊跟着一個以下兩種形式之一的注釋,就說它有一個“import comment”:

package math // import "path"
package math /* import "path" * /

           

go指令将拒絕安裝帶有import注釋的包,除非該包被導入路徑引用。通過這種方式,導入注釋讓包作者確定使用了自定義導入路徑,而不是到底層代碼托管站點的直接路徑。

詳情請參見https://golang.org/s/go14customimport。

25. package lists說明

Many commands apply to a set of packages:

通常,[packages]是一個導入路徑清單。

導入路徑,該路徑是根路徑或以。或. .元素被解釋為檔案系統路徑,并表示該目錄中的包。

否則,導入路徑P表示在目錄DIR/src/P中找到的包,在GOPATH環境變量中列出了一些DIR(參見’go help GOPATH ')。

如果沒有給出導入路徑,則該操作将應用于目前目錄中的包。

有三個保留的路徑名不應該被用go工具建構的包使用:

-“main”表示獨立可執行檔案中的頂級包。

-“all”展開到所有GOPATH樹中的所有包目錄。例如,'go list all’列出本地系統上的所有包。

-“std”類似于所有的,隻是擴充到了标準Go庫中的包。

如果導入路徑包含一個或多個“…”通配符,那麼它就是一個模式,每個通配符都可以比對任何字元串,包括空字元串和包含斜杠的字元串。這樣的模式擴充到在GOPATH樹中找到的所有名稱與模式比對的包目錄。作為特例,x/…比對x和x的子目錄。例如,net/…。在子目錄中擴充為網絡和包。

導入路徑還可以命名要從遠端存儲庫下載下傳的包。運作’go help importpath’擷取詳細資訊。

程式中的每個包必須有一個唯一的導入路徑。按照慣例,這是通過用屬于您的唯一字首開始每個路徑來安排的。例如,在谷歌内部使用的路徑都以’谷歌’開頭,而表示遠端存儲庫的路徑以代碼的路徑開頭,例如’code.google.com/p/project’。

作為一種特殊情況,如果包清單是來自單個目錄的.go檔案清單,則該指令将應用于完全由這些檔案組成的單個合成包,忽略這些檔案中的任何建構限制,并忽略目錄中的任何其他檔案。

go工具會忽略以“。”或“_”開頭的目錄和檔案名,如名為“testdata”的目錄。

25. 測試标志說明

'go test’指令接受應用于’go test’本身的标志和應用于結果二進制測試的标志。

一些标志控制概要檔案,并編寫适合“go工具pprof”的執行概要檔案;運作“go tool pprof help”擷取更多資訊。pprof的——alloc_space、——alloc_objects和——show_bytes選項控制資訊的顯示方式。

'go test’指令可以識别以下标志,并控制任何測試的執行:

-bench regexp
    Run benchmarks matching the regular expression.
    By default, no benchmarks run. To run all benchmarks,
    use '-bench .' or '-bench=.'.

-benchmem
    Print memory allocation statistics for benchmarks.

-benchtime t
    Run enough iterations of each benchmark to take t, specified
    as a time.Duration (for example, -benchtime 1h30s).
    The default is 1 second (1s).

-blockprofile block.out
    Write a goroutine blocking profile to the specified file
    when all tests are complete.
    Writes test binary as -c would.

-blockprofilerate n
    Control the detail provided in goroutine blocking profiles by
    calling runtime.SetBlockProfileRate with n.
    See 'godoc runtime SetBlockProfileRate'.
    The profiler aims to sample, on average, one blocking event every
    n nanoseconds the program spends blocked.  By default,
    if -test.blockprofile is set without this flag, all blocking events
    are recorded, equivalent to -test.blockprofilerate=1.

-cover
    Enable coverage analysis.

-covermode set,count,atomic
    Set the mode for coverage analysis for the package[s]
    being tested. The default is "set" unless -race is enabled,
    in which case it is "atomic".
    The values:
    set: bool: does this statement run?
    count: int: how many times does this statement run?
    atomic: int: count, but correct in multithreaded tests;
        significantly more expensive.
    Sets -cover.

-coverpkg pkg1,pkg2,pkg3
    Apply coverage analysis in each test to the given list of packages.
    The default is for each test to analyze only the package being tested.
    Packages are specified as import paths.
    Sets -cover.

-coverprofile cover.out
    Write a coverage profile to the file after all tests have passed.
    Sets -cover.

-cpu 1,2,4
    Specify a list of GOMAXPROCS values for which the tests or
    benchmarks should be executed.  The default is the current value
    of GOMAXPROCS.

-cpuprofile cpu.out
    Write a CPU profile to the specified file before exiting.
    Writes test binary as -c would.

-memprofile mem.out
    Write a memory profile to the file after all tests have passed.
    Writes test binary as -c would.

-memprofilerate n
    Enable more precise (and expensive) memory profiles by setting
    runtime.MemProfileRate.  See 'godoc runtime MemProfileRate'.
    To profile all memory allocations, use -test.memprofilerate=1
    and pass --alloc_space flag to the pprof tool.

-outputdir directory
    Place output files from profiling in the specified directory,
    by default the directory in which "go test" is running.

-parallel n
    Allow parallel execution of test functions that call t.Parallel.
    The value of this flag is the maximum number of tests to run
    simultaneously; by default, it is set to the value of GOMAXPROCS.

-run regexp
    Run only those tests and examples matching the regular
    expression.

-short
    Tell long-running tests to shorten their run time.
    It is off by default but set during all.bash so that installing
    the Go tree can run a sanity check but not spend time running
    exhaustive tests.

-timeout t
    If a test runs longer than t, panic.

-v
    Verbose output: log all tests as they are run. Also print all
    text from Log and Logf calls even if the test succeeds.
           

測試二進制檔案稱為pkg.test,其中pkg是包含包源的目錄名,可以在使用’go test -c’建構它之後直接調用它。當直接調用測試二進制檔案時,每個标準标志名都必須加上’test ‘字首。’,如-test.run=TestMyFunc或-test.v。

當運作’go test’時,上面沒有列出的标記将不加更改地傳遞。例如,指令:

go test -x -v -cpuprofile=prof.out -dir=testdata -update
           

将編譯測試二進制檔案,然後作為

pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
           

生成概要檔案的測試标志(除了覆寫率)也将測試二進制檔案留在pkg.test中,以便在分析概要檔案時使用。

“go test”不能識别的标志必須放在任何指定的包裹後面。

26. 測試功能說明

'go test’指令期望在"*_test. exe "中找到test、benchmark和示例函數。Go”對應于測試包的檔案。

測試函數是一個名為TestXXX的函數(其中XXX是任何不以小寫字母開頭的字母數字字元串),并且應該有簽名,

基準函數是一個名為BenchmarkXXX的函數,它應該具有簽名,

示例函數類似于測試函數,但不是使用*testing。T報告成功或失敗,将輸出列印到os.Stdout。該輸出将與函數的“output:”注釋進行比較,“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.
}
           

當整個測試檔案包含單個示例函數、至少一個其他函數、類型、變量或常量聲明,并且沒有測試或基準函數時,它将作為示例呈現。

有關更多資訊,請參見測試包的文檔。

繼續閱讀