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的編譯執行流程 這篇介紹。bash

關於編譯,go tool還有一些更細節的命令,好比compile、link等。有興趣能夠去了解下。網絡

包的管理

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/goquery下載安裝goquery的過程,以下:

$ 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命令的快速體驗爲目標,概要式地介紹了幾乎全部的命令。在對它們有了基本認識後,在之後遇到問題時,咱們才能想到它們,以及更快地掌握和使用它們。

相關文章
相關標籤/搜索