Go微服务实战
上QQ阅读APP看书,第一时间看更新

6.1.2 Go工具

Go语言提供了标准工具,利用这些工具,工程师可以方便地进行下载、查询、构建、格式化、测试、安装代码包等操作,这组标准工具称为Go工具(Go tool)。

Go工具是一组命令集,可以实现几组重要的功能,比如包管理器、构建系统、测试驱动等。Go工具的命令行接口有十几个子命令,具体可以运行go help来查看:


Go is a tool for managing Go source code.

Usage:

    go <command> [arguments]

The commands are:

    bug         start a bug report
    build       compile packages and dependencies
    clean       remove object files and cached files
    doc         show documentation for package or symbol
    env         print Go environment information
    fix          update packages to use new APIs
    fmt         gofmt (reformat) package sources
    generate    generate Go files by processing source
    get         download and install packages and dependencies
    install     compile and install packages and dependencies
    list        list packages or modules
    mod         module maintenance
    run         compile and run Go program
    test        test packages
    tool        run specified go tool
    version     print Go version
    vet         report likely mistakes in packages

可以看到,只是命令就有这么多,这还不包括命令后面可以带有的参数,Go语言提供的命令工具是十分全面的。

Go工具的风格被称为“瑞士军刀”风格,一方面囊括了绝大多数常用的命令,另一方面,每个命令都是最小化配置,使用更简单。为了实现最小化配置,很多用法都需要靠约定来达成。比如每个路径下只允许有一个package,这样找到一个源文件的package后就可以方便地根据路径找到这个包内所有的文件。

使用Go工具的时候基本不需要配置,部分仅仅需要很少的配置。Go语言通过环境变量的方式来实现相应的配置,现在来看一下如下环境变量。

(1)GOPATH

这是用户必须配置的变量,很多时候甚至只需要配置这一个变量,后面介绍的其他变量可以不配置。GOPATH用于指定工作空间的根目录,如果要在一台计算机上改变工作空间,则通过该环境变量切换到其他的路径。GOPATH下有三个子目录:src、pkg和bin,src子目录用于存放源文件,pkg子目录用于存放编译后的文件包,而bin子目录用于存放可执行程序。

(2)GOROOT

GOROOT是一个环境变量,用于保存Go语言标准包的根目录。大多数情况下只需要理解这个变量的意义即可,而不需要手动设置,因为GOROOT会默认使用Go语言的安装目录。

(3)GOOS和GOARCH

GOOS指定目标操作系统(比如Linux、Windows或Android等),GOARCH用于存储指定目标处理器的架构(比如arm、amd64等)。这两个环境变量在我们进行编译时,特别是在交叉编译时会用到。

前面介绍了四个常用的环境变量,除此之外还有一些不常用的环境变量,读者可以使用go env命令查看各个环境变量及对应的值,下面是执行结果的一部分:


$go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/liujinliang/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
…

在介绍了Go工具的环境变量后,就要介绍具体的go命令了,这些命令能够帮助我们完成文档管理、编译或测试等工作,下面选取几个重要的命令进行介绍。

(1)go get

可以通过该命令从互联网资源上下载包,比如从GitHub、Bitbucket等网站下载代码库。前面提到的MySQL的驱动github.com/go-sql-driver/mysql,就是GitHub的代码库,可以通过如下代码下载:


go get -u github.com/go-sql-driver/mysql

参数-u代表下载包的最新版本。go get命令本质上包含了两个步骤:安装和编译,相当于包含了后面要介绍的go install和go build。go get可以使用的参数见表6-1。

表6-1 go get参数说明

(2)go build

该命令的作用是编译指定的源文件或源码包以及它们依赖的包,如果包的名字是main,则会创建可执行程序。go build可以在要编译的包路径下直接执行而不需要指明包名,默认为编译当前路径的包;也可以把导入路径作为参数放到go build后面,这样就可以在任意路径下执行编译了。

在log包路径下可以不指定包,命令如下:


log$ go build

或者在任意路径下执行如下命令:


$ go build log

go build可以编译多个go文件,只需要用空格隔开,都跟在go build后面即可,此操作要求这几个文件都在同一个包内,如果包内依赖了其他包会自动编译,不用指定包名称。

如果编译的是main包,则要保证包中有main函数,否则无法编译通过。如果main包执行go build命令,则会输出可执行文件,默认是main函数所在源文件名去掉.go后缀。

go build常用的参数见表6-2。

表6-2 go build参数说明

注意

在执行go build命令时,目标程序会检查目标代码的所有依赖以及依赖的依赖,直到检查完最末层的依赖,如果发现循环依赖则编译会报错并停止。

(3)go install

了解了go build后,再理解go install就容易了。go install的作用也是编译源文件,而且用法和go build基本一致。下面来看一下go install的特点及与go build的区别。

▪go install编译产生的可执行文件以其所在的目录名命名。

▪go install将编译产生的可执行文件放在bin目录下,而go build产生的可执行文件与源文件同路径。

▪go install将可执行文件依赖的包编译后放在pkg目录下。

其实现在回看go get,就是git clone+go install的功能组合。

(4)go list

该命令的主要作用是查看包的信息,如果要查看一个包是否在工作空间中,可以通过如下命令实现:


$ go list github.com/go-sql-driver/mysql

如果要查看工作空间所有的包,可用如下命令:


$ go list

还有一种比较常用的方式是查找包的完整描述信息,这时要使用-json参数来实现:


$ go list -json fmt
{
    "Dir": "/usr/local/Cellar/go/1.12.6/libexec/src/fmt",
    "ImportPath": "fmt",
    "Name": "fmt",
    "Doc": "Package fmt implements formatted I/O with functions analogous to <br />        C's printf and scanf.",
    "Target": "/usr/local/Cellar/go/1.12.6/libexec/pkg/darwin_amd64/fmt.a",
    "Root": "/usr/local/Cellar/go/1.12.6/libexec",
    "Match": [
        "fmt"
    ],
    "Goroot": true,
    "Standard": true,
    "GoFiles": [
        "doc.go",
        "format.go",
        "print.go",
        "scan.go"
    ],

    …

上述命令会返回所有的元数据信息。

若想知道关于go list的更多参数和用法,可以执行go help list命令来查看。

(5)go doc与godoc

任何编程语言都鼓励编写良好的辅助文档,在Go语言中尤其如此。Go语言提供了两种查看文档的方式,即go doc与godoc。如果要在终端直接打印文档信息,可以使用go doc;使用godoc,则可以通过参数生成Web格式的文档,方便通过浏览器查看。

用户可以直接通过go doc <方法或包>来查看信息,此命令可以打印接口、函数、方法、变量的信息,当然要求首字母大写,比如查看fmt.Println函数:


$ go doc fmt.Println
func Println(a ...interface{}) (n int, err error)
    Println formats using the default formats for its operands and writes to
    standard output. Spaces are always added between operands and a newline is
    appended. It returns the number of bytes written and any write error
encountered.

go doc是Go工具关于文档的标准功能,体现小,执行迅速,在编程的过程中如果要了解某个函数、方法等,可以直接使用,特别是对于不熟悉的标准功能。go doc可以选择使用的参数见表6-3。

表6-3 go doc参数说明

如果要生成体系化的Web页面,则需要使用godoc。godoc有两种使用方式,即有-http参数和没有-http参数的情况。

不添加-http参数的情况下,godoc的用法和go doc很接近,也可以直接打印包的信息,比如godoc fmt。

若添加-http参数,就是以http的方式查看文档,比如godoc -http=:3030命令,相当于启动了一个Web服务,可以通过http://localhost:3030来查看文档。

注意

文档非常重要,很多程序员都是先写文档再写代码,建议读者也采用这种方式,便于完善思路,也有利于别人复用自己的代码。

除了上面介绍的比较重要的几个Go工具命令外,还有go run、go test等命令。本章后续内容会对go test进行介绍,而go run和go build就很像是编译完后加上了执行这一步。