Go 笔记之 Go 命令快速体验

上篇文章利用go run和go build命令分析介绍了GO的编译执行流程。GO提供给咱们的命令固然远不止这两个。本文将在所能及的范围内,尽可能地介绍GO提供的全部命令,从而实现对它们有个总体的认识。html

概述

除了gofmt与godoc外,GO中的命令通常均可经过go命令调用,这些命令可理解为go的子命令,查看下命令列表,以下:git

$ go
Go is a tool for managing Go source code.
Go是管理Golang源码的工具

Usage:
使用方式:
        go <command> [arguments]
        go <命令> [参数]

The commands are:
涉及的命令包括:

        bug         start a bug report
                    提交bug报告,执行后会开启浏览器并转到github的issue,当前的配置与环境都会自动填写到issue中
        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
                    可用于go新旧版本之间的代码迁移,修正代码兼容问题
        fmt         gofmt (reformat) package sources
                    按规范格式化源码
        generate    generate Go files by processing source
                    扫描源码注释,相似//go:generate command argument...实现生成go文件
        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
                    编译与执行Go程序
        test        test packages
                    测试包
        tool        run specified go tool
                    运行go提供的一些特定工具,好比pprof
        version     print Go version
                    打印go版本信息
        vet         report likely mistakes in packages
                    检查与报告代码包中的错误
        ...

输出的介绍大体翻译了下,其中部分命令也做了些介绍。除了go的子命令,go tool下也有些更底层的命令,执行go tool便可查看:github

$ go tool
addr2line  能够调用栈的地址转化为文件和行号
asm        和汇编有关的命令,没搞清楚如何使用
buildid    彷佛用在编译时,根据文件内容生成hash
cgo        可帮助咱们实如今GO中调用C语言代码
compile    用于编译源码生成.o文件
cover      可用于分析测试覆盖率
dist       帮助引导、构建和测试go
doc        测试下来彷佛和go doc效果同样,都是用于文章管理
fix        用于解决不一样版本间代码不兼容问题,和go fix做用同样
link       用于库的连接
nm         可列出如对象文件.o,可执行文件或.a库文件中的函数变量符号等信息
objdump    反汇编命令
pack       彷佛是个打包压缩命令
pprof      自带的性能分析工具
test2json  用于把测试文件转化可读的json格式
tour       启动本地的tour教程,可见GO团队真的很用心
trace      可用于问题诊断与调式的工具
go tool的输出默认没有任何文字说明,这里的介绍是我收集总结出来的,可能有些错误。

整体而言,我把GO中命令分为几个大类:golang

  • 源码编译
  • 包的管理
  • 代码规范
  • 测试相关
  • 调试优化
  • 其余命令

GO的命令不少,很难在一篇文章中把每一个都介绍清楚。接下来只作些简单演示说明,详细的介绍待之后有了具体场景在详细说明。web

源码编译

go build、go run 两个命令可归于源码编译类的命令,是入门学习首先要掌握的,故而在前篇文章已经作了详细介绍。json

go build用于编译可执行文件和库文件,参数能够是源码目录、.go文件。演示以下:浏览器

$ go build # 目录
$ go build main.go # .go文件
$ go build main.go math.go data.go # .go文件列表

go run和build有不少类似点,它们都会编译源码。不一样的是,go run只能用于可执行源码(即main包源码)的编译。接收参数为.go文件。演示以下:缓存

$ go run main.go
$ go run main.go math.go data.go

详细了解,能够看下 详解GO的编译执行流程 这篇介绍。网络

关于编译,go tool还有一些更细节的命令,好比compile、link等。有兴趣能够去了解下。svn

包的管理

GO的包管理是由语言包自带,这点不一样于其余语言,如Java、Python、PHP等。从当前我所了解的来看,GO没有提供包管理仓库,而是直接使用的版本管理系统做为仓库,支持如git、svn、mercurial等。而用于包管理的命令有go install、go get、go list等。

go install用于源码包的编译与安装。虽然这里也涉及到编译,但从名字就能够看出,该命令重在强调安装。以前build命令在编译非main包会生成缓存文件,main包会生成执行文件并拷贝到当前目录。而install会将它们安装到指定的文件。假设有名为math的包,执行以下命令:

$ go install math  # 非main包,最终生成文件 $GOPATH/pkg/xxx/xxx/math.a。
$ go install entry # 是main包,最终生成文件 $GOBIN/entry

go get用于从互联网安装更新包和依赖,相似于其余语言包管理器的install。不一样于install,它多出网络下载这步,大概可理解为 go get 等价于 git/svn等下载 + git install。咱们能够演示下从http://github.com/PuerkitoBio...,以下:

$ go get -v github.com/PuerkitoBio/goquery
golang.org/x/net/html/atom
golang.org/x/net/html
github.com/andybalholm/cascadia
github.com/PuerkitoBio/goquery

从上面能够看出,go get不只下载了goquery,还下载了相应的依赖。执行完成后,GOPATH目录下能够找到goquery的源码与编译后的.a库文件。

go list可用于输出包的信息,接口的参数和在源码中import的路径相同,下面演示一些案例:

$ go list fmt   # 查看某包
fmt
$ go list fmt net/http # 查看多个包
fmt
net/http
$ go list --json fmt # 查看包的具体信息
{
    "Dir": "/usr/local/go/src/fmt",
    "ImportPath": "fmt",
    "Name": "fmt",
    "Doc": "Package fmt implements formatted I/O with functions analogous to C's printf and scanf.",
    "Target": "/usr/local/go/pkg/darwin_amd64/fmt.a",
    "Root": "/usr/local/go",
    "Match": [
        "fmt"
    ],
    "Goroot": true,
    "Standard": true,
    "GoFiles": [
        "doc.go",

        ...

        "scan.go"
    ],
    "Imports": [
        "errors",
        ...
        "unicode/utf8"
    ],
    "Deps": [
        "errors",
         ...
        "unicode/utf8",
        "unsafe"
    ],
    "TestGoFiles": [
        "export_test.go"
    ],
    "XTestGoFiles": [
        "example_test.go",
         ...
        "stringer_test.go"
    ],
    "XTestImports": [
        "bufio",

        ...

        "unicode/utf8"
    ]
}

详情信息部分展现内容比较多,包含源码路径、导入路径、依赖了哪些包等一系列信息。

代码规范

这类命令能够帮助咱们规范代码的格式,减小代码发生错误的概率,其中主要有go fmt、go vet和go fix三个命令。

go fmt的做用是代码的格式化。为了让咱们把更多时间花在开发工做上,GO官方制定了标准的代码规范并go fmt实现规范代码。假设有main.go文件内容以下:

package main

func main() {
    a   :=  x +     y
}

咱们只需执行go fmt main.go文件,而后再次打开main.go文件:

package main

func main() {
    a := x + y
}

格式化已经完成。关于代码格式化还有一个更具体的命令:gofmt,go fmt是它的某个特殊形式:gofmt -l -w。

go vet是一个用于检查GO语言静态语法的工具。GO语言的语法是很是严格的,如不能定义未使用的变量、变量类型必须显式转化等等。示例,假设有main.go文件内容以下:

package main

func main() {
    a := 1 + 2
        b := 1
}

使用go vet执行源码检查,输出结果以下:

$ go vet main.go
# command-line-arguments [command-line-arguments.test]
./main.go:4:5: a declared and not used
./main.go:5:5: b declared and not used

咱们被告知,变量a和b声明但并无使用。

go fix主要用于处理代码的兼容性问题,例如go1以前老版本的代码转化到go1。可是有点遗憾的是,没找到该命令的演示案例。咱们平时应该不多用到。

测试相关

GO也提供与相关的命令,为咱们提供了一条方便验证咱们代码的途径。与测试有关的命令有go test、go tool cover 和 go tool test2json。

go test可用于运行测试代码,以此验证程序逻辑的正确性能。具体演示下,示例代码包含两部分,分别是功能代码和测试代码。功能代码在math.go文件中,以下:

package math

func Add(x, y int) int {
    return x + y
}

测试用例的代码在math_test.go文件中,以下:

package math

import "testing"

func Test_Add(t *testing.T) {
    r := Add(1, 2)
    if r != 3 {
        t.FailNow()
    }
}

接下来咱们能够执行go test命令启动测试用例,以下:

$ go test math_test.go math.go
ok      command-line-arguments

结果显示,测试执行成功,Add函数功能正常。咱们能够把测试代码编译成可执行文件,以下:

$ go test math_test.go math.go -o math.test

查看下会发现此时目录下多出了编译好的math.test可执行测试文件。

go cover可用于分析测试覆盖率。好比上面的测试案例,咱们能够生成覆盖率文件,以下:

$ go test *.go -coverprofile=coverage.out

go cover 提供多种方式分析测试覆盖率,这里演示下如何用html展现测试结果,以下:

$ go tool cover --html=size_coverage.out

显示测试覆盖率为100%。咱们这里的测试用例比较简单,因此到达了全面覆盖。

go tool test2json可用于将go test测试结果转化为json格式。这里须要使用以前生成的测试执行文件,示例以下:

$ go tool test2json ./math.test -test.v
{"Action":"run","Test":"Test_Add"}
{"Action":"output","Test":"Test_Add","Output":"=== RUN   Test_Add\n"}
{"Action":"output","Test":"Test_Add","Output":"--- PASS: Test_Add (0.00s)\n"}
{"Action":"pass","Test":"Test_Add"}
{"Action":"output","Output":"PASS\n"}
{"Action":"pass"}

测试结果以json格式打印出来。虽然我对专业的测试不太了解,可是也明白结构化的输出是比较容易程序化分析的。

调试优化

完成代码开发后,可能时刻会遇到一些bug或者性能问题。GO提供了go tool pprof、go tool trace、go tool addr2line和go tool nm等一系列命令,可用于代码调试优化。

go tool pprof可用于帮助咱们分析程序收集的性能数据,好比CPU、内存等数据。以官方提供的示例为例吧,博客地址在 博客。示例代码在benchgraffiti。

go tool trace 可用于追踪程序执行状况。go tool pprof能够经过cpu和内存数据分析出程序的瓶颈。

go tool addr2line能够将地址转化对应源码的文件和行号,很是方便的便于咱们调式问题。

具体的案例就不演示了。这部分的命令稍微有点复杂,待后面有了具体案例再来补充。

其余命令

GO中还提供了不少辅助命令。这些命令有go bug、go doc、go tool tourl等。

go bug会直接启动浏览器并进入github的go项目的issue之下,还会把用户当前环境信息自动添加到issue中。以下执行go bug以后跳转的页面:

因而可知,GO的开发团队真的很是用心,作了不少简化咱们工做的事情。

go doc为咱们提供了快速查看文档的途径,好比查看fmt文档,咱们只需执行go doc fmt,fmt相关的文档便会输出到控制台。咱们也能够像官网文档那样用浏览器查看文档,只需执行godoc -http=:6060,便会启动一个本地的web服务。咱们访问localhost:6060就能看到一个几乎和官网同样的页面,示例以下:

go tool tourl是官方提供的本地搭建tour教程的方式。咱们只需执行go tool tour便会自动启动浏览器并进入教程首页。

到这里咱们能够发现,即便因为一些缘由使咱们没法访问GO的官网,但有了这些工具,咱们也能够愉快地进行GO的学习。

总结

本篇文章以GO命令的快速体验为目标,概要式地介绍了几乎全部的命令。在对它们有了基本认识后,在之后遇到问题时,咱们才能想到它们,以及更快地掌握和使用它们。

相关文章
相关标签/搜索