Go語言工具簡介 - Honeybadger
在本文中,Ayooluwa Isaiah總結了Go for Rubyists系列,並介紹了go工具。
工具通常被認為是Go生態系統中最強大的方面之一。go命令本身是本文將要討論的許多工具的門戶。透過學習此處討論的每個工具,您在Go專案上工作時將變得更加高效,並快速,可靠地執行常見任務。
檢視環境變數
go env命令用於顯示有關當前Go環境的資訊。這是此命令輸出的示例:
GO111MODULE="on" GOARCH="amd64" GOBIN="/home/ayo/go/bin" GOCACHE="/home/ayo/.cache/go-build" GOENV="/home/ayo/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/ayo/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/lib/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/dev/null" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build145204762=/tmp/go-build -gno-record-gcc-switches" |
如果要檢視特定變數的值,可以將它們作為引數傳遞給go env命令:
$ go env GOPATH GOROOT GOBIN /home/ayo/go /usr/lib/go /home/ayo/go/bin |
可以使用以下命令訪問每個變數的文件:
go help environmental |
使用go run執行程式碼
假設您有一個main.go包含以下程式碼的檔案,
package main import "fmt" func main() { fmt.Println("Welcome to Go!") } |
您可以使用go run命令來執行它,正如我們在本系列中已經多次看到的那樣:
$ go run main.go Welcome to Go! |
該go run命令將編譯程式,在/tmp 目錄中建立可執行檔案,然後一步執行該二進位制檔案。如果要一次執行多個檔案,可以將它們全部作為引數傳遞給go run:
$ go run main.go time.go input.go |
或者,您可以使用萬用字元:
$ go run *.go |
從Go v1.11開始,您還可以一次執行整個程式包:
$ go run ./foo # Run the package in the `foo` directory $ go run . # Run the package in the current directory |
使用gofmt格式化程式碼
如果您一直在編寫Go程式碼一段時間,就會知道對於如何格式化程式碼有嚴格的約定。gofmt命令對所有現有的Go程式碼強制執行這些約定。
上一節中顯示的程式碼段格式不正確,因此讓我們使用對其進行格式設定gofmt,如下所示:
$ gofmt main.go package main import "fmt" func main() { fmt.Println("Welcome to Go!") } |
這將格式化原始檔中的程式碼,並將結果列印到標準輸出中。如果要用格式化的輸出覆蓋原始檔,則需要新增-w標誌。
$ gofmt -w main.go |
要遞迴格式化Go原始檔(當前目錄和子目錄),請指定a.作為引數gofmt。
gofmt . |
修復匯入語句
必須先匯入包,然後才能在程式碼中使用包。否則將失敗,則程式碼將無法編譯,並且將顯示錯誤。給定main.go檔案中的以下程式碼,
package main func main() { fmt.Println("Welcome to Go!") } |
如果嘗試執行該程式,應該看到以下錯誤:
$ go run main.go # command-line-arguments ./main.go:4:2: undefined: fmt |
在編譯程式碼之前,fmt必須先匯入軟體包。您可以手動新增必要的程式碼,也可以使用goimports命令為您新增必要的import語句。
$ goimports main.go package main import "fmt" func main() { fmt.Println("Welcome to Go!") } |
該命令還會刪除不再引用的所有匯入軟體包,並以與gofmt相同的樣式設定程式碼格式。因此,您也可以將其go imports 視為的替代品gofmt。
如果將編輯器設定為在儲存Go原始檔時執行,則goimports價值將變得顯而易見。這樣,您就不必擔心在使用軟體包之前匯入軟體包或匯入不再需要的語句。儲存檔案後,它將自動為您完成。大多數程式碼編輯器都有某種外掛或設定可對此提供幫助。
構建你的專案
要為您的程式生成可執行二進位制檔案,請使用go build命令。這將在當前目錄中輸出一個二進位制檔案:
$ go build $ ./demo Welcome to Go! |
生成的二進位制檔案go build特定於您的作業系統體系結構,並且包含執行程式所需的所有內容。因此,您可以將其轉移到具有相同體系結構的另一臺計算機上,即使未安裝Go,它也可以相同的方式執行。
如果要交叉編譯非您自己的體系結構的二進位制檔案,您所需要做的就是 在執行命令之前更改GOOS和GOARCH環境變數的值go build。
例如,以下命令可用於為64位Windows計算機生成二進位制檔案:
$ GOOS=windows GOARCH=amd64 go build |
要針對Linux,macOS,ARM,Web Assembly或其他目標進行編譯,請參考Go文件 以檢視GOOS和GOARCH可用的組合。
安裝Go二進位制檔案
如果您希望能夠從源目錄外部執行,go install可替代go build。
假設您的main.go檔案位於一個名為的目錄中demo,以下命令將demo在您的$GOPATH/bin目錄中建立一個二進位制檔案。
$ go install |
在大多數計算機上$GOPATH應是$HOME/go。您可以使用以下go env命令進行檢查 :
$ go env GOPATH /home/ayo/go |
如果要列出 $GOPATH/bin目錄下內,你會看到一個demo二進位制檔案
$ ls $GOPATH/bin demo |
這個二進位制檔案可以在你檔案系統任何位置透過執行demo命令。但是僅當$GOPATH/bin目錄已新增到您$PATH中時,此方法才起作用。
$ demo Welcome to Go! |
列出包的資訊
預設呼叫會go list返回您當前所在目錄或提供的包路徑的匯入路徑的名稱:
$ go list github.com/ayoisaiah/demo $ go list github.com/joho/godotenv github.com/joho/godotenv |
我們可以使用-f標誌來自定義go list命令的輸出,該標誌使您可以執行Go模板,模板可以訪問go工具的內部資料結構。例如,您可以使用以下命令列出的fmt名稱:
$ go list -f "{{ .Name }}" fmt fmt |
它本身並不是很有趣,但是還有:您可以使用{{ .Imports }}模板列印軟體包的所有依賴項。這是fmt包的輸出:
$ go list -f "{{ .Imports }}" fmt <p class="indent">[errors internal/fmtsort io math os reflect strconv sync unicode/utf8] |
或者,您可以列出軟體包的完整傳遞依賴項集:
$ go list -f "{{ .Deps }}" fmt <p class="indent">[errors internal/bytealg internal/cpu internal/fmtsort internal/oserror internal/poll internal/race internal/reflectlite internal/syscall/execenv internal/syscall/unix internal/testlog io math math/bits os reflect runtime runtime/internal/atomic runtime/internal/math runtime/internal/sys sort strconv sync sync/atomic syscall time unicode unicode/utf8 unsafe] |
您還可以使用以下go list命令檢查對依賴項和子依賴項的更新:
$ go list -m -u all |
或者,檢查對特定依賴項的更新:
$ go list -m -u go.mongodb.org/mongo-driver go.mongodb.org/mongo-driver v1.1.1 [v1.4.0] |
您可以使用該go list命令執行更多操作。可以在documentation查閱可能與該命令一起使用的標誌和其他模板變數。
顯示包或符號的文件
go doc命令將列印與由其引數標識的專案關聯的文件註釋。它接受零,一或兩個引數。
要在當前目錄中顯示軟體包的軟體包文件,請使用不帶任何引數的命令:
$ go doc |
如果程式包是命令(main程式包),則除非-cmd提供了標誌,否則輸出中將省略匯出符號的文件。
go doc透過將軟體包的匯入路徑作為命令的引數傳遞,我們可以使用該命令檢視任何軟體包的文件:
$ go doc encoding/json package json // import "encoding/json" Package json implements encoding and decoding of JSON as defined in RFC 7159. The mapping between JSON and Go values is described in the documentation for the Marshal and Unmarshal functions. <p class="indent">[truncated for brevity] |
如果要檢視包中特定方法的文件,只需將其作為第二個引數傳遞給go doc:
$ go doc encoding/json Marshal |
下面是第二種命令引數,godoc將所有Go軟體包(包括您下載的任何第三方依賴項)的文件顯示為網頁。執行該命令將預設在埠6060上啟動Web伺服器,但是您可以使用該-http標誌更改地址。
$ godoc -http=:6060 |
執行靜態分析
go vet命令可以幫助檢測程式碼中可能未被編譯器捕獲的可疑結構。這些可能未必會阻止您的程式碼編譯,但會影響程式碼質量,例如無法訪問的程式碼,不必要的分配以及格式字串引數格式錯誤。
$ go vet main.go # Run go vet on the `main.go` file $ go vet . # Run go vet on all the files in the current directory $ go vet ./... # Run go vet recursively on all the files in the current directory |
該命令由幾個分析器工具組成,這些工具在此處列出,每個工具都對檔案執行不同的檢查。
預設情況下,go vet執行命令時將執行所有檢查。如果您只想執行特定的檢查(忽略所有其他檢查),則將分析器的名稱作為標記包括在內,並將其設定為true。這是一個printf僅執行檢查的示例 :
$ go vet -printf=true ./... |
但是,將-printf=false標誌傳遞給go vet將執行除printf以外的所有檢查。
$ go vet -printf=false ./... |
向專案新增依賴項
假設您啟用了Go模組go run,則go build,或go install將下載實現程式中import語句所需的所有外部依賴項。預設情況下,如果沒有可用的標記版本,則將下載最新的標記版本或最新的提交。
如果您需要下載依賴關係的特定版本,而不是預設情況下透過Go獲取,則可以使用該go get命令。您可以指定特定版本或提交雜湊:
$ go get github.com/joho/godotenv@v1.2.0 $ go get github.com/joho/godotenv@d6ee687 |
該方法可根據需要用於升級或降級依賴項。任何下載的依賴項都儲存在位於的模組快取中 $GOPATH/pkg/mod。您可以使用該go clean命令一次性清除所有專案的模組快取:
$ go clean -modcache |
使用Go模組
這是有效使用模組需要了解的命令的摘要:
- go mod init 將初始化專案中的模組。
- go mod tidy清理未使用的依賴項或新增缺失的依賴項。在確認對程式碼進行任何更改之前,請確保執行此命令。
- go mod download 將所有模組下載到本地快取。
- go mod vendor將所有第三方依賴項複製到vendor專案根目錄中的資料夾中。
- go mod edit可用於將go.mod檔案中的依賴項替換為本地或分支版本。例如,如果需要使用派生直到補丁在上游被合併,請使用以下程式碼:
go mod edit -replace=github.com/gizak/termui=github.com/ayoisaiah/termui |
測試和基準測試程式碼
Go具有一個稱為的內建測試命令go test和一個testing包,可以將其組合以提供簡單但完整的單元測試體驗。該test 工具還包括基準測試和程式碼覆蓋率選項,可幫助您進一步分析程式碼。
讓我們編寫一個簡單的測試來演示該test 工具的一些功能。修改main.go檔案中的程式碼,如下所示:
package main import "fmt" func welcome() string { return "Welcome!" } func main() { fmt.Println(welcome()) } |
然後,將測試新增到同一目錄中的單獨檔案main_test.go中:
package main import "testing" func TestWelcome(t *testing.T) { expected := "Welcome to Go!" str := welcome() if str != expected { t.Errorf("String was incorrect, got: %s, want: %s.", str, expected) } } |
如果在終端中執行go test,它將失敗:
$ go test --- FAIL: TestSum (0.00s) main_test.go:9: String was incorrect, got: Welcome!, want: Welcome to Go!. FAIL exit status 1 FAIL github.com/ayoisaiah/demo 0.002s |
我們可以透過修改檔案中welcome 函式的返回值來使main.go透過測試。
func welcome() string { return "Welcome to Go!" } |
現在,測試應該成功透過:
$ go test PASS ok github.com/ayoisaiah/demo 0.002s |
如果您有許多具有測試功能的測試檔案,但只想選擇性地執行其中一些,則可以使用該-run標誌。它接受一個正規表示式字串以匹配要執行的測試函式:
$ go test -run=^TestWelcome$ . # Run top-level tests matching "TestWelcome" $ go test -run= String . # Run top-level tests matching "String" such as "TestStringConcatenation" |
您還應該知道以下測試標誌,這些標誌在測試Go程式時通常會派上用場:
- -v標誌啟用詳細模式,以便將測試的名稱列印在輸出中。
- -short標誌跳過長時間執行的測試。
- -failfast一次失敗測試後,該標誌停止測試。
- -count標誌連續執行多次測試,這對於您要檢查間歇性故障很有用。
程式碼覆蓋率
要檢視程式碼覆蓋狀態,請使用-cover標誌,如下所示:
$ go test -cover PASS coverage: 50.0% of statements ok github.com/ayoisaiah/demo 0.002s |
您還可以使用該-coverprofile標誌生成coverage配置檔案。這使您可以更詳細地研究程式碼覆蓋率結果:
$ go test -coverprofile=coverage.out |
coverage.out執行上述命令後,您將在當前目錄中找到一個檔案。該檔案中包含的資訊可用於輸出HTML檔案,其中包含現有測試已覆蓋的確切程式碼行。
$ go tool cover -html=coverage.out |
執行此命令時,將彈出一個瀏覽器視窗,其中綠色的覆蓋線和紅色的覆蓋線。
標杆管理
Go中的基準測試工具已被廣泛認為是一種衡量Go程式碼效能的可靠方法。_test.go就像測試一樣,基準放置在檔案中。這是一個比較Go中不同字串連線方法的效能的示例:
// main_test.go package main import ( "bytes" "strings" "testing" ) var s1 = "random" const LIMIT = 1000 func BenchmarkConcatenationOperator(b *testing.B) { var q string for i := 0; i < b.N; i++ { for j := 0; j < LIMIT; j++ { q = q + s1 } q = "" } b.ReportAllocs() } func BenchmarkStringBuilder(b *testing.B) { var q strings.Builder for i := 0; i < b.N; i++ { for j := 0; j < LIMIT; j++ { q.WriteString(s1) } q.Reset() } b.ReportAllocs() } func BenchmarkBytesBuffer(b *testing.B) { var q bytes.Buffer for i := 0; i < b.N; i++ { for j := 0; j < LIMIT; j++ { q.WriteString(s1) } q.Reset() } b.ReportAllocs() } func BenchmarkByteSlice(b *testing.B) { var q []byte for i := 0; i < b.N; i++ { for j := 0; j < LIMIT; j++ { q = append(q, s1...) } q = nil } b.ReportAllocs() } |
可以使用以下go test -bench=.命令呼叫此基準測試:
$ go test -bench=. goos: linux goarch: amd64 pkg: github.com/ayoisaiah/demo BenchmarkConcatenationOperator-4 1718 655509 ns/op 3212609 B/op 999 allocs/op BenchmarkStringBuilder-4 105122 11625 ns/op 21240 B/op 13 allocs/op BenchmarkBytesBuffer-4 121896 9230 ns/op 0 B/op 0 allocs/op BenchmarkByteSlice-4 131947 9903 ns/op 21240 B/op 13 allocs/op PASS ok github.com/ayoisaiah/demo 5.166s |
如您所見,串聯運算子是最慢的,每次操作為655509納秒,而bytes.Buffer最快的則為9230納秒。以這種方式編寫基準測試是確定效能改進或可重複性下降的最佳方法。
檢測競爭條件
go工具包含一個執行緒競爭探測器,可以透過-race選件啟用 。這對於發現併發系統中的問題很有用,這可能導致崩潰和記憶體損壞。
$ go test -race ./... $ go run -race main.go $ go build -race ./... $ go install -race ./... |
相關文章
- Go語言學習(1) - 簡介Go
- 簡單介紹Go 語言單例模式Go單例模式
- Go語言介紹Go
- Go語言簡史Go
- 簡單介紹Go語言常用的打log方式Go
- 8 語言模型簡介模型
- 簡單介紹Go 語言常見的一些坑Go
- 番外2: go語言寫的簡要資料同步工具Go
- go語言開發有哪些工具Go
- Go語言交叉編譯工具goxGo編譯
- python之程式語言(簡介)01Python
- Java程式語言特點簡介Java
- C語言基礎-C簡介C語言
- groovy 程式語言簡單介紹
- Go語言————1、初識GO語言Go
- go語言Json解析實用工具 - gjsonGoJSON
- GO語言一個簡單的工程Go
- Go語言詳細介紹:logo和版本Go
- 一、Go語言基礎:入門應用簡介及常用命令Go
- C語言-GCC的簡單介紹C語言GC
- 一、程式語言簡介與C++C++
- Go語言開發的PaaS工具有哪些?go學習Go
- 用JavaScript實現一門程式語言 2 (λanguage語言簡介)JavaScript
- 使用go語言開發hive匯出工具GoHive
- GO語言————2、GO語言環境安裝Go
- Go 語言開源 CI/CD 容器 Drone 介紹Go
- 人工智慧--自然語言處理簡介人工智慧自然語言處理
- 【Go語言入門系列】(八)Go語言是不是面嚮物件語言?Go物件
- Go_go語言初探Go
- 帶讀 |《Go in Action》(中文:Go語言實戰)打包和工具鏈Go
- 五款最棒的Go語言開發工具?Go
- badamczewski/PowerUp:Rust/Go語言的反編譯工具RustGo編譯
- Go語言mapGo
- go 語言切片Go
- go 語言常量Go
- go語言使用Go
- Snow——簡單易用的 Go 語言業務框架Go框架
- Go 語言開發工具 LiteIDE X35 釋出,支援 Go modulesGoIDE