Go命令行文档-go

go 是重要的管理源码的工具。包含一系列常用子命令。

go command [arguments]

子命令包含:

build       go build 编译包和依赖库
clean       go clean 移除目标文件
doc         显示包或符号文档
env         go env 打印Go环境变量信息
bug         开启bug报告
fix         go fix 运行包修复工具
fmt         格式化包代码
generate    go generate 在进程中生成Go文件
get         go get 下载安装包和依赖库
install     go install 编译安装包和依赖库
list        go list 显示包列表
run         go run 编译运行Go程序
test        go test 包测试
tool        go tool 运行指定的go命令行工具
version     go version 打印Go版本
vet         go vet 运行代码审查工具

在命令行执行 go help [command] 可以获取更多详细信息。

额外的帮助主题topic:

c           Go与C相互调用
buildmode   显示编译模式
filetype    文件类型
gopath      GOPATH
environment 环境变量
importpath  导入路径语法
packages    包列表说明
testflag    测试命令行参数说明
testfunc    测试函数说明

在命令行执行 go help [topic] 可以获取更多详细信息。

go build 编译包和依赖库

go build [-o output] [-i] [build flags] [packages]

build 命令编译由导入路径命名的包及其依赖项,但不会安装编译生成的二进制文件到bin目录。

如果要传入的参数是.go文件列表,则构建时将它们视为单个包下的源文件列表(不在一个包会出现不可预知的错误)。

当编译的是一个单独的main包时,会以包内的第一个源文件的文件名来命名生成的可执行文件( 例如 go build ed.go rx.go 会生成 ed 或 ed.exe),或以源代码文件夹名称来命名生成的可执行文件( 例如 go build unix/sam 会生成 sam 或 sam.exe)。注意 .exe文件是windows环境下的可执行文件后缀。

编译多个包或单个非main包时,会构建编译,但放弃生成可执行文件,仅检查是否可以构建包。

编译时会忽略以'_test.go'结尾的文件。

仅在编译单个包时才允许使用 -o,会强制将生成的可执行文件或对象写入指定的输出文件,而不是采用默认的命名方式。

-i 标志会安装作为目标依赖项的软件包。

构建标志由build,clean,get,install,list,run和test命令共享:

-a
	强制重新编译所有包。
-n
	打印命令但不运行。
-p n
	n表示程序数量,使 build 或 test 可以并行执行。
	默认值为CPU可用数。
-race
	启用数据竞争检测。
	仅支持 linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
-msan
	启用与存储器清理程序的互操作。
	仅支持将 Clang/LLVM 作为主 C 编译器的 linux/amd64 系统。
-v
	包编译时打印其名称。
-work
	打印临时工作目录的名称并且退出时不会将其删除。
-x
	打印编译命令。

-asmflags 'flag list'
	传递给 go tool asm 调用的参数。
-buildmode mode
	使用的编译模式。参见 go help buildmode。
-compiler name
	运行时使用的编译器名称。gccgo 或 gc。
-gccgoflags 'arg list'
	参数传递给 gccgo compiler/linker 调用。
-gcflags 'arg list'
	参数传递给 go tool compile 调用。
-installsuffix suffix
	在软件包安装目录的名称中使用一个后缀, 以保持输出与默认构建分离。
	如果使用-race标志,则安装后缀会自动设置为 race。对于-msan同样如此。
    使用需要非默认编译标志的-buildmode选项有类似效果。
-ldflags 'flag list'
	参数传递给 go tool link 调用。
-linkshared
	与以前创建的共享库链接 -buildmode=shared。
-pkgdir dir
	安装并加载所有从dir而不是通常位置的软件包。
	例如,在使用非标准配置进行构建时,
    使用 -pkgdir 将生成的包保存在一个单独的位置。
-tags 'tag list'
	一个由空格分隔的构建标签列表。
-toolexec 'cmd args'
	一个用来调用像 vet 和 asm 这样的工具链程序。
	为了替代运行 asm, 可以执行命令
	'cmd args /path/to/asm <arguments for asm>'.

所有采用参数列表的标志都接受空格分隔的字符串列表。要在列表中的元素中嵌入空格,请使用单引号或双引号。

有关指定软件包的更多信息,请参阅 go help packages 。有关安装软件包和二进制文件的更多信息, 请运行'go help gopath'。有关Go和C/C++相互调用的更多信息,请运行 go help c 。

注意:build 遵循类似于 go help gopath 的约定。然而并非所有的项目都会遵循这些约定。 自行约定或使用单独的软件构建系统的安装可以选择使用较低级别的调用,例如 go tool compile 和 go tool link,以降低编译的开销。

go clean 移除目标文件

go clean [-i] [-r] [-n] [-x] [build flags] [packages]

clean 从目录内删除目标文件。go命令将临时目录中的大部分对象构建在一起,所以clean主要关注其他工具留下的目标文件。

具体来说,clean将每个与导入路径对应的源目录中删除以下文件:

_obj/            旧的 obj 文件夹,Makefiles 所生成
_test/           旧的 test 文件夹, Makefiles 所生成
_testmain.go     旧的 gotest 文件, Makefiles 所生成
test.out         旧的 test log文件, Makefiles 所生成
build.out        旧的 test log文件,  Makefiles 所生成
*.[568ao]        object 文件, Makefiles 所生成

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

在列表中,DIR表示目录的最终路径元素,MAINFILE是构建包时不包含的目录中任何Go源文件的基本名称。

-i标志会导致clean删除相应的已安装的归档文件或二进制文件(即 go install 所创建的)。

-n标志会导致clean打印它将执行的remove命令,但不会运行它们。

-r标志导致clean被递归地应用于由导入路径命名的包的所有依赖关系。

-x标志会导致clean在执行它们时打印相应的删除命令。

更多细节,请查看 go help build。

有关指定软件包的更多信息,请参阅 go help packages 。

go doc 显示软件包/符号的文档

go doc [-u] [-c] [package|[package.]symbol[.methodOrField]]

doc 打印与其参数(包,const,func,type,var,method或struct字段)标识的项目相关的文档注释, 后面跟着该项目下的每个第一级项目的单行摘要(包的包级声明,类型的方法等)。

doc命令接收零个,一个或者两个参数。

如果传递零个参数,即:

go doc

它打印当前目录中的包的包文档。如果是main包,除非提供 -cmd 标志, 否则软件包的导出符号将从文档中消失 猜测是为了保护main包

当使用一个参数运行时,参数被视为要记录的项目的Go语法表示。参数选择取决于在GOROOT和GOPATH中安装的内容,以及参数的形式,如下:

go doc <pkg>
go doc <sym>[.<methodOrField>]
go doc [<pkg>.]<sym>[.<methodOrField>]
go doc [<pkg>.][<sym>.]<methodOrField>

这个列表中的第一项与参数匹配的是文档所在项目。 (请参阅下面的示例。)如果参数以大写字母开头,则假定在当前目录中标识符号或方法。

对于包,扫描的顺序是按照广度优先原则在词汇上确定。也就是说,所呈现的包是与搜索相匹配, 并且在层次结构最接近词根。在扫描GOPATH之前总是扫描GOROOT目录树。

如果没有指定或匹配的包,则选择当前目录中的包,所以 go doc Foo 显示当前包中符号Foo的文档。

包路径必须是正确的路径或路径的正确后缀。go doc 的包机制不适用于 . 和 ...。

当使用两个参数运行时,第一个必须是完整的包路径(不只是后缀),第二个是带有方法或结构字段的符号或符号。这与godoc接受的语法类似:

go doc <pkg> <sym>[.<methodOrField>]

在所有形式中,匹配符号时,参数中的小写字母匹配任意一种情况,但大写字母完全匹配。这意味着如果不同的符号具有不同的情况,那么在一个包中可能有多个小写参数匹配。如果发生这种情况,将打印所有匹配的文档。

例如:

go doc
	显示当前包文档。
go doc Foo
	显示当前包下 Fo 文档。
	(Foo以大写字母开头,所以无法匹配包路径。)
go doc encoding/json
	显示 encoding/json 包文档。
go doc json
	显示 encoding/json 包文档的缩写形式。
go doc json.Number (or go doc json.number)
	显示 json.Number 的文档和方法摘要。
go doc json.Number.Int64 (or 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 的新函数的文档。
	(html/template 排列在 text/template前)
go doc text/template.new # One argument
	显示 text/template 的新函数的文档。
go doc text/template new # Two arguments
	显示 text/template 的新函数的文档。

至少在当前的树中,这些调用都打印出来 json.Decoder 解码方法的文档:

go doc json.Decoder.Decode
go doc json.decoder.decode
go doc json.decode
cd go/src/encoding/json; go doc decode

参数

-c
	Respect case when matching symbols.
-cmd
	把main包视作普通包。
	否则,当显示包的顶级文档时main包的主要导出符号被隐藏。
-u
	显示未导出文档以及导出的符号,方法和字段。

go env 打印Go环境变量

go env [-json] [var ...]

env 命令输出Go环境变量信息。

默认情况下,env将信息打印为一个shell脚本(在Windows上是一个批处理文件)。如果给出一个或多个变量名作为参数,env将在每行上打印每个命名变量的值。

-json标志以JSON格式打印环境而不是shell脚本。

go bug 开启异常报告

go bug

bug 命令打开默认浏览器并启动一个新的错误报告。该报告包含有用的系统信息。

go fix 运行包修复工具

go fix [packages]

fix 命令由导入路径命名的包上执行 go fix命令。

有关fix的更多信息,参阅 fix。有关指定软件包的更多信息,参阅 go help packages 。

要使用特定的选项运行修复程序,运行 go tool fix。

go fmt 格式化源码

go fmt [-n] [-x] [packages]

fmt 在由导入路径命名的包上运行命令 gofmt -l -w 。它会打印被修改的文件的名字。

有关gofmt的更多信息,请参阅gofmt 。有关指定软件包的更多信息,请参阅 go help packages 。

-n标志打印将被执行的命令。 -x标志在执行时打印命令。

要运行具有特定选项的gofmt,请运行gofmt本身。

go generate 在进程中生成Go文件

go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]

根据现有文件中的指令描述生成命令。这些命令可以运行任何进程,目的是创建或更新Go代码文件。

生成扫描文件的指令:

//go:generate command argument...

(注意:"//go"中没有前后中间都没有空格)命令是要运行的生成器,对应于可以在本地运行的可执行文件。 它必须位于shell路径(gofmt),完全限定路径(/usr/you/bin/mytool)或命令别名中。

请注意,go generate 不解析文件,所以在注释或多行字符串中看起来像指令的行将被视为指令。

指令的参数是以空格分隔或包含在双引号内的字符串,在运行时作为单独的参数传递给生成器。

引用的字符串使用Go语法,并在执行前进行语法检查;引用的字符串作为发生器的单个参数出现。

go generate 可以设置如下变量:

$GOARCH
	CPU架构(arm,amd64等)
$GOOS
	执行操作系统(linux,windows等)
$GOFILE
	文件的基本名称。
$GOLINE
	指令在源代码中的行号。
$GOPACKAGE
	包含该指令的文件包的名称。
$DOLLAR
	美元符号。

除了变量替换和引用字符串评估之外,在命令行上不执行诸如'通配符'之类的特殊处理。

作为运行该命令的最后一步,任何具有字母数字名称的环境变量(如$GOFILE 或 $HOME)的调用都会在整个命令行中展开。

所有操作系统上的变量扩展语法都是 $NAME。由于评估的顺序,变量甚至会在引用的字符串内被扩展。如果未设置变量NAME,则$NAME展开为空字符串。

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

这个指令仅对该源文件的其余部分,指定字符串xxx由参数标识。这可以用来创建别名或处理多字符生成器。例如:

//go:generate -command foo go tool foo

指定命令 foo 表示生成器 go tool foo 。

进程包按照命令行中给定的顺序挨个生成。如果命令行列出.go文件,则将其视为单个包。 在包内生成按文件名顺序处理的源文件。在源文件中按照出现的顺序挨个生成。

如果任何生成器返回错误状态码,go generate 将跳过该包接下来处理任务。

有关 build 标志的更多信息,请参阅 go help build 。

有关指定软件包的更多信息,请参阅 go help packages 。

go get 下载安装包和依赖库

go get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]

get 命令下载由导入路径命名的包及其依赖关系。然后会执行安装,就像 go install。

-d标志导致下载软件包后停止;也就是说,它不安装软件包。

-f标志仅在-u设置时有效,强制get -u不检验每个包是否已从其导入路径隐含的代码存储仓库中检出。如果下载源是原始的本地分支,这可能很有用。

-fix标志导致在解析依赖关系或构建代码之前,在下载的包上运行修复工具。

-insecure标志允许从存储库获取并使用不安全的方案(如HTTP)解析自定义域。谨慎使用。

-t标志导致get同时下载构建指定软件包的测试所需的软件包。

-u标志使用网络来更新命名包及其依赖关系。默认情况下,get使用网络检出缺少的包,但不使用它来查找现有包的更新。

-v标志启用详细的进度和调试输出。

get 也接受 build 标志控制安装。查看 go help build。

当 get 检出新的包时,get创建目标目录 GOPATH/src/<import-path>。如果GOPATH包含多个条目,get使用第一个。更多细节请查看 go help gopath。

在检出或更新包时,get 查找与本地安装的Go版本匹配的分支或标签。例如,如果本地正在运行版本 go1 的包,则搜索名为 go1 的分支或标记。如果不存在这样的版本,则检索包的默认分支。

当 go get 检查或更新一个Git仓库时,它也更新仓库引用的任何git子模块。

get 从不检出或更新存储在 vendor 目录中的代码。

有关指定软件包的更多信息,请参阅 go help packages。

要了解更多关于 go get 如何获取并下载,参阅 go help importpath

go install 编译安装包和依赖库

go install [build flags] [packages]

install 编译并安装由导入路径命名的包及其依赖关系。

了解更多,参阅 go help build 和 go help packages。

go list 显示包列表

go list [-e] [-f format] [-json] [build flags] [packages]

list 列出了由导入路径命名的包,每行一个。

默认输出会显示包导入路径:

bytes
encoding/json
github.com/gorilla/mux
golang.org/x/net/html

-f标志使用包模板的语法为列表指定一个替代格式。默认输出等同于-f 模板ImportPath变量。传递给模板的结构是:

type Package struct {
    Dir           string // 包含软件包源的目录
    ImportPath    string // 在dir中导入包的路径
    ImportComment string // package语句中导入注释的路径
    Name          string // 包名
    Doc           string // 包文档字符串
    Target        string // 安装路径
    Shlib         string // 包含此包的共享库(仅在链接时设置)
    Goroot        bool   // 这个包是否包含在 Go root
    Standard      bool   // 这个包是否属于标准库
    Stale         bool   // go install 是否会为这个包做什么
    StaleReason   string // Stale==true时的解释
    Root          string // 包含此包的 Go root 或 Go path 文件夹路径
    ConflictDir   string // 该文件夹在 $GOPATH 中的影子目录
    BinaryOnly    bool   // binary-only package: 无法使用源重新编译

    // 源文件
    GoFiles        []string // .go 源码文件 (包含 Cgo文件, TestGo文件, XTestGo文件)
    CgoFiles       []string // 导入了 "C" 包的.go 源码文件
    IgnoredGoFiles []string // 根据build限制略过的.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 文件

    // Cgo 指令
    CgoCFLAGS    []string // cgo: C 编译器标志(flag)
    CgoCPPFLAGS  []string // cgo: C 预处理器标志
    CgoCXXFLAGS  []string // cgo: C++ 编译器标志
    CgoFFLAGS    []string // cgo: Fortran 编译器标志
    CgoLDFLAGS   []string // cgo: 链接器标志
    CgoPkgConfig []string // cgo: 包配置名称(pkg-config names)

    // 依赖信息
    Imports      []string // 本包使用的导入路径
    Deps         []string // 所有(递归)导入的依赖关系
    TestImports  []string // 导出的(imports from)TestGoFiles
    XTestImports []string // 导出的(imports from)XTestGoFiles

    // 错误信息
    Incomplete bool            // 本包或包依赖是否发生错误
    Error      *PackageError   // 错误加载包
    DepsErrors []*PackageError // 错误加载依赖
}

存储在 vendor 目录中的软件包会报告一个ImportPath,其中包含 vendor 目录的路径(例如,d/vendor/p而不是p), 以便ImportPath给予软件包副本唯一标识。Imports,Deps,TestImports和XTestImport列表还包含这些扩展的导入路径。查看golang.org/s/go15vendor以了解更多。

如果有错误信息的话

type PackageError struct {
    ImportStack   []string // 命令行使用的最短包路径
    Pos           string   // 错误位置 (文件:行号:内容)
    Err           string   // 错误
}

模板函数 join 调用strings.Join。

模板函数 context 返回build上下文(context),定义如下:

type Context struct {
	GOARCH        string   // 目标CPU架构
	GOOS          string   // 目标操作系统
	GOROOT        string   // Go root
	GOPATH        string   // Go path
	CgoEnabled    bool     // cgo是否可用
	UseAllFiles   bool     // 使用文件,不管+构建行,文件名
	Compiler      string   // 编译器在计算目标路径时进行的假设
	BuildTags     []string // build约束
	ReleaseTags   []string // 可兼容版本
	InstallSuffix string   // install文件夹的后缀
}

有关这些字段的含义的更多信息,请参阅go/build软件包的Context类型的文档。

-json标志使包数据以JSON格式打印而不是使用模板格式。

-e标志改变错误包的处理,包含那些不能被发现或者格式错误的包。默认情况下,list命令会为每个错误的包打印一个标准错误的错误,并在通常的打印过程中忽略这些包。 使用-e标志,list命令不会将错误打印到标准错误,而是用通常的打印处理错误的包。错误的包将有一个非空的ImportPath和一个非零的错误字段;其他信息可能会也可能不会丢失(归零)。

go run 编译运行Go程序

go run [build flags] [-exec xprog] gofiles... [arguments...]

运行包含go源码的main包。Go源文件被定义为以文字'.go'后缀结尾的文件。

默认情况下,'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 ...'允许在模拟器或其他执行方法可用时执行交叉编译的程序。

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.go')或'.'开头的文件被忽略。可以包含函数测试、基准测试和样例测试。 参阅'go help testfunc'以了解更多。每个列出的软件包都会执行单独的测试二进制文件。

如果包的后缀使用'_test'声明,将被编译为一个单独的包,然后与主测试二进制文件链接并运行。

go工具将忽略名为'testdata'的目录,使其可以保存测试所需的辅助数据。

默认情况下,go test不需要参数。它用当前目录中的代码编译并运行测试。

生成的测试包在临时目录中,所以不会干扰非测试安装。

除了build的标志,go test还处理以下标志:

-args
    传递命令行的其余部分(在-args之后的所有内容)到测试二进制文件,解释不变。
    因为这个标志消耗了命令行的其余部分,
    包列表(如果存在)必须出现在此标志之前。

-c
    编译测试二进制到pkg.test,但不运行它
    (其中pkg是程序包导入路径的最后一个元素).
    文件名可以用-o标志改变。

-exec xprog
    使用xprog运行测试二进制文件。 与'go run'一样。

-i
   安装测试包依赖而不运行测试。

-o file
    将测试二进制编译到指定的文件。
    测试会运行(除非指定了-c或-i)。

测试二进制文件还接受控制测试执行的标志;这些标志也可以通过'go test'进行访问。查看 go help testflag 以了解更多。

go tool 运行指定的go命令行工具

go tool [-n] command [args...]

tool 运行由参数标识的go工具命令。没有参数时它打印已知工具的列表(显示子命令列表)。

-n标志会打印可准备执行的命令但不执行它。

查看go tool子命令帮助,可以在命令行输入'go tool 子命令 -h'。

go version 打印Go版本

go version

version 打印当前Go版本,调用了 runtime.Version。

go vet 运行代码审查工具

go vet [-n] [-x] [build flags] [vet flags] [packages]

vet 在导入路径指定的包上运行Go vet命令。

-n标志打印将被执行的命令。 -x标志在执行时打印被执行的命令。

Go与C相互调用

在Go和C/C++代码之间有两种不同的方式来调用。

第一种方法是使用cgo,它是Go发行版的一部分。详情查看cgocgo。

第二种方法是使用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++编译器。

显示编译模式

'go build'和'go install'命令带有一个-buildmode参数,用于指示要构建哪种类型的目标文件。目前支持的值有:

-buildmode=archive
	Build the listed non-main packages into .a files. Packages named
	main are ignored.

-buildmode=c-archive
	Build the listed main package, plus all packages it imports,
	into a C archive file. The only callable symbols will be those
	functions exported using a cgo //export comment. Requires
	exactly one main package to be listed.

-buildmode=c-shared
	Build the listed main package, plus all packages it imports,
	into a C shared library. The only callable symbols will
	be those functions exported using a cgo //export comment.
	Requires exactly one main package to be listed.

-buildmode=default
	Listed main packages are built into executables and listed
	non-main packages are built into .a files (the default
	behavior).

-buildmode=shared
	Combine all the listed non-main packages into a single shared
	library that will be used when building with the -linkshared
	option. Packages named main are ignored.

-buildmode=exe
	Build the listed main packages and everything they import into
	executables. Packages not named main are ignored.

-buildmode=pie
	Build the listed main packages and everything they import into
	position independent executables (PIE). Packages not named
	main are ignored.

-buildmode=plugin
	Build the listed main packages, plus all packages that they
	import, into a Go plugin. Packages not named main are ignored.

文件类型

go命令检查每个目录中受限制文件的内容。它根据文件名的扩展名来标识要检查的文件。这些扩展名是:

.go
	Go source files.
.c, .h
	C source files.
	If the package uses cgo or SWIG, these will be compiled with the
	OS-native compiler (typically gcc); otherwise they will
	trigger an error.
.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 or SWIG, these will be assembled with the
	OS-native assembler (typically gcc (sic)); otherwise they
	will be assembled with the Go assembler.
.swig, .swigcxx
	SWIG definition files.
.syso
	System object files.

除.syso以外的每种类型的文件都可能包含构建约束, 但go命令将停止扫描如果文件甲中的第一个文件不包含(不是空行或 //-style)的build注释。更多详细信息,请参阅go/build包文档。

非测试Go源文件还可以包含//go:binary-only-package注释,标明仅用于文档,不得用于构建包二进制文件。更多详细信息,请参阅go/build包文档。

GOPATH

Go路径用于解析导入语句。它由go/build包实现并文档化。

GOPATH环境变量列出了寻找Go代码的地方。在Unix上,该值是冒号分隔的字符串。在Windows上,该值是以分号分隔的字符串。在Plan 9中,该值是一个列表。

如果环境变量未设置,GOPATH将默认为用户主目录中的'go'子目录(Unix下的$HOME/go ,Windows下的%USERPROFILE%\go),除非该目录已被Go占用(unless that directory holds a Go distribution)。运行 go env GOPATH 以查看当前 GOPATH 值。

查看详细安装文档以了解如何设置自定义GOPATH。

GOPATH中列出的每个目录必须具有规定的结构:

src目录包含代码源文件。src下面的路径决定了导入路径或可执行文件的名称。

pkg目录保存已安装的软件包对象。每个目标操作系统和体系结构对都有自己的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/               (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中列出的每个目录以查找源代码,但是新的包总是被下载到列表中的第一个目录中。

查看如何编写go代码查看示例。

Internal目录

名为'internal'的目录中或以下的代码只能由以'internal'的父级目录树中的代码进行导入。以下是上述目录布局的扩展版本:

/home/user/go/
    src/
        crash/
            bang/              (go code in package bang)
                b.go
        foo/                   (go code in package foo)
            f.go
            bar/               (go code in package bar)
                x.go
            internal/
                baz/           (go code in package baz)
                    z.go
            quux/              (go code in package main)
                y.go

z.go中的代码被导入为'foo/internal/baz',但该导入语句只能出现在以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已经支持使用本地外部依赖关系的副本来满足这些依赖的导入,通常称为 vendoring。

名为'vendor'的目录下面的代码仅可由'vendor'父级目录树中的代码进行导入,并且只能使用导入路径,该路径省略了直到vendor的前缀(vendor也被省略)。

下面是上一节的示例,但是将'internal'目录重命名为'vendor',并添加了一个新的foo/vendor/crash/bang目录:

/home/user/go/
    src/
        crash/
            bang/              (go code in package bang)
                b.go
        foo/                   (go code in package foo)
            f.go
            bar/               (go code in package bar)
                x.go
            vendor/
                crash/
                    bang/      (go code in package bang)
                        b.go
                baz/           (go code in package baz)
                    z.go
            quux/              (go code in package main)
                y.go

其内部具有相同的可见性规则,但是z.go中的代码被导入为'baz',而不是'foo/vendor/baz'。

代码树中 vendor 目录下的代码隐藏较高目录中的代码。 在foo的子目录中,导入'crash/bang'会调用'foo/vendor/crash/bang',而不是上一层极目录下的的'crash/bang'。

vendor 目录中的代码不受导入路径检查的影响。

当 go get 检出或更新一个Git仓库时,它现在也会更新子模块。

vendor 目录不会影响 go get 第一次检出新存储库的位置:总是会放在主要的GOPATH中,而不是在 vendor 子目录中。

环境变量

go命令及其调用的工具检查了几个不同的环境变量。可以通过运行'go env NAME'来查看系统的默认值,其中NAME是变量的名称。

通用环境变量:

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.
GOOS
	The operating system for which to compile code.
	Examples are linux, darwin, windows, netbsd.
GOPATH
	For more details see: 'go help gopath'.
GORACE
	Options for the race detector.
	See https://golang.org/doc/articles/race_detector.html.
GOROOT
	The root of the go tree.

用于cgo的环境变量:

CC
	The command to use to compile C code.
CGO_ENABLED
	Whether the cgo command is supported. Either 0 or 1.
CGO_CFLAGS
	Flags that cgo will pass to the compiler when compiling
	C code.
CGO_CPPFLAGS
	Flags that cgo will pass to the compiler when compiling
	C or C++ code.
CGO_CXXFLAGS
	Flags that cgo will pass to the compiler when compiling
	C++ code.
CGO_FFLAGS
	Flags that cgo will pass to the compiler when compiling
	Fortran code.
CGO_LDFLAGS
	Flags that cgo will pass to the compiler when linking.
CXX
	The command to use to compile C++ code.
PKG_CONFIG
	Path to pkg-config tool.

用于特定架构的环境变量:

GOARM
	For GOARCH=arm, the ARM architecture for which to compile.
	Valid values are 5, 6, 7.
GO386
	For GOARCH=386, the floating point instruction set.
	Valid values are 387, sse2.

特殊用途的环境变量:

GOROOT_FINAL
	The root of the installed Go tree, when it is
	installed in a location other than where it is built.
	File names in stack traces are rewritten from GOROOT to
	GOROOT_FINAL.
GO_EXTLINK_ENABLED
	Whether the linker should use external linking mode
	when using -linkmode=auto with code that uses cgo.
	Set to 0 to disable external linking mode, 1 to enable it.
GIT_ALLOW_PROTOCOL
	Defined by Git. A colon-separated list of schemes that are allowed to be used
	with git fetch/clone. If set, any scheme not explicitly mentioned will be
	considered insecure by 'go get'.

导入路径语法

导入路径(请参阅'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程序,则可以在该程序的导入语句中使用相对路径来引用附近的代码,这些代码也不在工作区中。 这使得在常规工作空间之外尝试小型多组件程序更加轻松,但这样的程序不能使用'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"

对于托管在其他服务器上的代码,可以使用版本控制类型对导入路径进行限定, 也可以通过https/http动态获取导入路径,并在HTML的<meta>标记中查找代码所在的位置。

声明代码的位置写在导入的路径之前:

repository.vcs/path

指定给定的存储库,使用或不使用.vcs后缀,指定版本控制系统,然后使用该存储库中的路径。支持的版本控制系统是:

Bazaar      .bzr
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')。

如果导入路径不是已知的代码托管站点,也缺少版本控制限定符,则转到工具将尝试通过https/http获取导入, 并在文档的HTML<head>中查找<meta>标记。

meta标签的形式是:

导入前缀是对应于存储库根目录。它必须是一个前缀或与'go get'一起提取的包的完全匹配。 如果不完全匹配,则会在前缀处进行另一个http请求,以验证<meta>标签是否匹配。

meta标签应尽可能早地出现在文件中。特别是,它应该出现在任何原始的JavaScript或CSS之前,以避免混淆go命令的受限解析器。

vcs是'git','hg','svn'之一,

repo-root 是包含一个方案的版本控制系统的根,不包含.vcs限定符

例如:

import "example.org/pkg/foo"

将导致以下请求:

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

如果该页面包含元标记

<meta name="go-import" content="example.org git https://code.org/r/p/exproj">

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

新下载的软件包会写入GOPATH环境变量中列出的第一个目录(有关更多详细信息, 请参阅:'go help gopath')。

go命令尝试下载适用于正在使用的Go版本的软件包版本。运行'go help get'获取更多信息。

导入路径检查

当上述自定义导入路径功能重定向到已知的代码托管站点时,每个生成的包都可能有两个导入路径:自定义域或已知的托管站点。

如果一个package语句紧跟着(在下一个换行符之前)这样的注释,就会被认为有一个'导包注释(import comment)':

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

go命令将拒绝安装带有导入注释的程序包,除非该导入路径被引用。 通过这种方式,包使用者可以确保使用自定义导入路径,而不是到底层代码托管站点的直接路径。

vendor目录下是不做导包路径检查的。这使得可以将代码复制到vendor中的备用位置,而无需更新导入注释。

查看https://golang.org/s/go14customimport查看更多细节。

包列表说明

对包可以使用这样的命令

go action [packages]

通常[packages]指的是导入的包列表。

导入路径是指根路径,及以.或..开始的被视为文件系统的路径,可以表示该目录中的包。

导入路径P表示在GOPATH环境变量中列出的某个DIR在目录DIR/src/P中找到的包(有关更多详细信息,请参阅:go help gopath)。

如果未提供导入路径,则操作将应用于当前目录。

路径有四个保留名称,在使用中不可用于go工具构建:

- 'main'表示独立可执行文件中最顶层的包。

- 'all'表示所有GOPATH树中的所有包目录。例如,'go list all'列出本地系统上的所有软件包。

- 'std'表示所有Go的标准库中的包。例如,'go list std'列出标准库中的所有软件包。

- 'cmd'表示Go存储库的命令及其内部库。

以'cmd/'开头的导入路径只能匹配Go存储库中的源代码。

如果导入路径包含一个或多个'...'通配符,每个可以匹配任何字符串,包括空字符串和包含斜杠的字符串。 这样会在所有GOPATH树中查找名称与之匹配的包目录。

为了使通用模式更方便,有两种特殊情况。首先,模式末尾的/...可以匹配一个空字符串,这样net/...就可以匹配net和http子目录中的net和packages。 其次,任何包含通配符的斜线分隔的元素,都不会与vendor包内的vendor元素匹配,因此./ ...不匹配./vendor或./mycode/vendor的子目录中的包, 而是./vendor/...和./mycode/vendor/...do。但是,请注意,名为vendor的目录本身包含代码不是一个vendor包: cmd/vendor将是一个名为vendor的命令,并且模式cmd/...匹配它。参阅golang.org/s/go15vendor了解更多。

导入路径也可以命名为从远程存储库下载的包。运行'去帮助导入路径'了解详情。

程序中的每个软件包都必须具有唯一的导入路径。按照惯例,你可以在每个路径前添加独一无二的前缀。 例如,Google内部使用的路径全部以'google'开头,表示远程存储库的路径以代码路径开始,如'github.com/user/repo'。

程序中的程序包不必具有唯一的程序包名称,但有两个保留的程序包名称具有特殊含义。名字main表示一个命令,而不是一个库。 命令内置于二进制文件中,不能导入。名字documentation指出目录中非Go程序的文档。documentation文档中的文件被go命令忽略。

作为特殊情况,如果软件包列表是来自单个目录的.go文件列表,目的是将这些文件组成单个的合成包,将忽略这些文件中的任何构建约束并忽略目录中的任何其他文件。

以'.'开头的目录和文件名或'_'被go工具忽略,就像名为'testdata'的目录一样。

测试命令行参数说明

go test命令同样接收test标志参数。

运行'go tool pprof -h',了解--alloc_space,--alloc_objects和--show_bytes选项是如何呈现信息的。

以下标志可以被'go test'识别并控制测试的执行:

-bench regexp
    运行仅与传入的正则匹配的基准测试。
    默认情况下,不运行基准测试。
    如果需要运行所有基准测试, 使用 '-bench .' 或 '-bench=.'。
    正则表达式被斜杠(/)字符拆分转换为正则表达式的序列,
    并且每个标志符需要与此顺序对应。
    可能匹配父结构用b.N = 1运行以确定子基准。
    例如,给定-bench = X/Y,匹配X的顶级基准在b.N=1的情况下运行,
    以找到任何匹配Y的子基准,然后完整地运行。

-benchtime t
    运行足够的迭代次数以满足参数 t, 该参数是
    time.Duration 类型(例如, -benchtime 1h30s)。
    默认为1秒。

-count n
    运行每个测试和基准n次(默认1)。
    如果设置了-cpu,则为每个GOMAXPROCS值运行n次。
    样例测试总是只运行一次。

-cover
    启用覆盖率分析。
    请注意,因为覆盖通过注释来源进行工作,
    编译前的代码,编译和测试失败
    启用覆盖范围可能会报告错误的行号。

-covermode set,count,atomic
    设置覆盖分析模式为。
    默认值是'set',除非-race已启用,在这种情况下它是'原子'的。
    set: bool: set模式是否开启?
    count: int: 该模式运行多少次?
    atomic: int: 计算运行次数,是原子的,对资源消耗更多。
    前提是启用了 -cover.

-coverpkg pkg1,pkg2,pkg3
    将测试的覆盖率分析应用到给定的软件包列表。
    默认是只分析被测试的包。
    包被指定为导入路径。
    前提是启用了 -cover.

-cpu 1,2,4
    为测试或基准测试设置GOMAXPROCS值列表。默认为当前系统可用GOMAXPROCS数。

-list regexp
    列出与正则表达式匹配的普通测试,基准或示例。
    不会执行测试。
    只会列出顶级测试。不会显示子测试或子基准测试。

-parallel n
    设置并行数量。
    允许并行执行调用t.Parallel测试函数。
    此标志的值是要运行的最大测试次数;
    默认情况下,它被设置为GOMAXPROCS的值。
    请注意,并行仅适用于单个测试二进制文件。
   'go test'命令可以并行的运行不同软件包的测试,(参阅'go help build')。

-run regexp
    只运行那些与正则表达式匹配的普通测试和样例测试。
    正则表达式被斜杠(/)字符拆分转换为正则表达式的序列,
    并且每个标志符需要与此顺序对应。
    可能匹配父结构用b.N = 1运行以确定子基准。
    例如,给定-bench = X/Y,匹配X的顶级基准在b.N=1的情况下运行,
    以找到任何匹配Y的子基准,然后完整地运行。

-short
    尽快完成测试。
    默认关闭。
    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 d
   设置超时时间。默认10分钟。
   超时会引发panic。

-v
    详细输出:打印运行时的所有测试信息,无论测试是否成功。
    Log和Logf中的文本也会被打印。

以下标志也被'go test'识别,并且可以用于在分析测试过程:

-benchmem
    打印基准测试的内存分析统计信息。

-blockprofile block.out
    测试完成时将goroutine阻塞记录写入指定文件。
    写入测试二进制文件的方式与 -c 类似。

-blockprofilerate n
    通过设置runtime.SetBlockProfileRate=n控制goroutine 阻塞分析提供的细节。
    参阅 'go doc runtime.SetBlockProfileRate'.
    分析器的目标是平均每隔一个阻塞事件进行采样,
    记录程序被阻塞花费的纳秒数。
    默认情况下相当于 -test.blockprofilerate=1。

-coverprofile cover.out
   在所有测试通过后,将覆盖率分析文件写入文件。
   前提是启用了 -cover.

-cpuprofile cpu.out
   在退出之前,将CPU分析文件写入指定的文件。
   写入测试二进制文件的方式与 -c 类似。

-memprofile mem.out
    所有测试都通过后,将内存分析文件写入文件。
    写入测试二进制文件的方式与 -c 类似。

-memprofilerate n
    通过设置runtime.MemProfileRate=n启用更精准的内存分配分析记录。
    参阅 'go doc runtime.MemProfileRate'。
    要分析所有内存分配,请使用-test.memprofilerate=1
    并将--alloc_space标志传递给pprof工具。

-mutexprofile mutex.out
    所有测试都通过后,将mutex竞争分析文件写入指定的文件。
    写入测试二进制文件的方式与 -c 类似。

-mutexprofilefraction n
    Sample 1 in n stack traces of goroutines holding a
    contended mutex.

-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的任一侧。

要将测试二进制文件的参数解释为已知标志或软件包名称,请使用-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被传递给测试二进制文件,而不是被解释为软件包列表。

测试函数说明

'go test'命令期望在与被测试包相对应的'*_test.go'文件中找到测试函数,基准测试和示例函数。

测试函数是一个名为TestXXX(其中XXX是任何不以小写字母开头的字母数字字符串),并应具有签名,

func TestXXX(t *testing.T) { ... }

基准测试是一个名为BenchmarkXXX的函数,

func BenchmarkXXX(b *testing.B) { ... }

一个示例函数与测试函数类似,但不使用*tests.T来报告成功或失败,而是将输出输出到os.Stdout。 如果函数中的最后一个注释以'Output:'开始,则输出与注释比较的结果(参阅下面的示例)。 如果最后一个注释以'Unordered output:'开头,则输出与注释进行比较,但是行的顺序将被忽略。 如果样例测试没有这样注释编译将不会执行,另外如果在"Output:" 后没有任何文本,将会被编译并执行,但没有任何输出。

这是一个样例测试的例子

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
}

在上面的例子中,该测试文件包含样例测试,并不包含标准测试或基准测试函数。