03.04 Go語言實戰筆記(二)

《Go語言實戰》讀書筆記,未完待續,第一時間看後續筆記。

在Go語言中,我們很多操作都是通過go命令進行的,比如我們要執行go文件的編譯,就需要使用go build命令,除了build命令之外,還有很多常用的命令,這一次我們就統一進行介紹,對常用命令有一個瞭解,這樣我們就可以更容易的開發我們的Go程序了。


Go語言實戰筆記(二)| Go開發工具


Go 開發工具概覽

go這個工具,別看名字短小,其實非常強大,是一個強大的開發工具,讓我們打開終端,看看這個工具有哪些能力。

<code>➜  ~ go
Go is a tool for managing Go source code.

Usage:

\tgo command [arguments]

The commands are:

\tbuild compile packages and dependencies
\tclean remove object files
\tdoc show documentation for package or symbol
\tenv print Go environment information
\tbug start a bug report
\tfix run go tool fix on packages
\tfmt run gofmt on package sources
\tgenerate generate Go files by processing source
\tget download and install packages and dependencies
\tinstall compile and install packages and dependencies
\tlist list packages
\trun compile and run Go program
\ttest test packages
\ttool run specified go tool
\tversion print Go version
\tvet run go tool vet on packages

Use "go help [command]" for more information about a command.

Additional help topics:

\tc calling between Go and C
\tbuildmode description of build modes
\tfiletype file types
\tgopath GOPATH environment variable
\tenvironment environment variables
\timportpath import path syntax

\tpackages description of package lists
\ttestflag description of testing flags
\ttestfunc description of testing functions

Use "go help [topic]" for more information about that topic./<code>

可以發現,go支持的子命令很多,同時還支持查看一些【主題】。我們可以使用go help [command]或者go help [topic]查看一些命令的使用幫助,或者關於某個主題的信息。大部分go的命令,都是接受一個全路徑的包名作為參數,比如我們經常用的go build。

go build

go build,是我們非常常用的命令,它可以啟動編譯,把我們的包和相關的依賴編譯成一個可執行的文件。

<code>usage: go build [-o output] [-i] [build flags] [packages]/<code>

go build的使用比較簡潔,所有的參數都可以忽略,直到只有go build,這個時候意味著使用當前目錄進行編譯,下面的幾條命令是等價的:

<code>go build

go build .

go build hello.go/<code>

以上這三種寫法,都是使用當前目錄編譯的意思。因為我們忽略了packages,所以自然就使用當前目錄進行編譯了。從這裡我們也可以推測出,go build本質上需要的是一個路徑,讓編譯器可以找到哪些需要編譯的go文件。packages其實是一個相對路徑,是相對於我們定義的GOROOT和GOPATH這兩個環境變量的,所以有了packages這個參數後,go build就可以知道哪些需要編譯的go文件了。

<code>go build flysnow.org/tools/<code>

這種方式是指定包的方式,這樣會明確的編譯我們這個包。當然我們也可以使用通配符。

<code>go build flysnow.org/tools/.../<code>

3個點表示匹配所有字符串,這樣go build就會編譯tools目錄下的所有包。

講到go build編譯,不能不提跨平臺編譯,Go提供了編譯鏈工具,可以讓我們在任何一個開發平臺上,編譯出其他平臺的可執行文件。

默認情況下,都是根據我們當前的機器生成的可執行文件,比如你的是Linux 64位,就會生成Linux 64位下的可執行文件,比如我的Mac,可以使用go env查看編譯環境,以下截取重要的部分。

<code>➜  ~ go env
GOARCH="amd64"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"/<code>

注意裡面兩個重要的環境變量GOOS和GOARCH,其中GOOS指的是目標操作系統,它的可用值為:

  1. darwin
  2. freebsd
  3. linux
  4. windows
  5. android
  6. dragonfly
  7. netbsd
  8. openbsd
  9. plan9
  10. solaris

一共支持10中操作系統。GOARCH指的是目標處理器的架構,目前支持的有:

  1. arm
  2. arm64
  3. 386
  4. amd64
  5. ppc64
  6. ppc64le
  7. mips64
  8. mips64le
  9. s390x

一共支持9中處理器的架構,GOOS和GOARCH組合起來,支持生成的可執行程序種類很多,具體組合參考https://golang.org/doc/install/source#environment。如果我們要生成不同平臺架構的可執行程序,只要改變這兩個環境變量就可以了,比如要生成linux 64位的程序,命令如下:

<code>GOOS=linux GOARCH=amd64 go build flysnow.org/hello/<code>

前面兩個賦值,是更改環境變量,這樣的好處是隻針對本次運行有效,不會更改我們默認的配置。

以上這些用法差不多夠我們用的了,更多關於go build的用戶可以通過以下命令查看:

<code>go help build/<code>


Go語言實戰筆記(二)| Go開發工具


go clean

在我們使用go build編譯的時候,會產生編譯生成的文件,尤其是在我們簽入代碼的時候,並不想把我們生成的文件也簽入到我們的Git代碼庫中,這時候我們可以手動刪除生成的文件,但是有時候會忘記,也很麻煩,不小心還是會提交到Git中。要解決這個問題,我們可以使用go clean,它可以清理我們編譯生成的文件,比如生成的可執行文件,生成obj對象等等。

<code>usage: go clean [-i] [-r] [-n] [-x] [build flags] [packages]/<code>

用法和go build基本一樣,這樣不再進行詳細舉例演示,可以參考go build的使用,更多關於go clean的使用,可以使用如下命令查看:

<code>go help clean/<code>

go run

go build是先編譯,然後我們在執行可以執行文件來運行我們的程序,需要兩步。go run這個命令就是可以把這兩步合成一步的命令,節省了我們錄入的時間,通過go run命令,我們可以直接看到輸出的結果。

<code>➜  ~ go help run
usage: go run [build flags] [-exec xprog] gofiles... [arguments...]

Run compiles and runs the main package comprising the named Go source files.

A Go source file is defined to be a file ending in a literal ".go" suffix.

By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
If the -exec flag is given, 'go run' invokes the binary using xprog:
\t'xprog a.out arguments...'.
If the -exec flag is not given, GOOS or GOARCH is different from the system
default, and a program named go_$GOOS_$GOARCH_exec can be found
on the current search path, 'go run' invokes the binary using that program,
for example 'go_nacl_386_exec a.out arguments...'. This allows execution of
cross-compiled programs when a simulator or other execution method is
available.

For more about build flags, see 'go help build'./<code>

go run命令需要一個go文件作為參數,這個go文件必須包含main包和main函數,這樣才可以運行,其他的參數和go build差不多。 在運行go run的時候,如果需要的話,我們可以給我們的程序傳遞參數,比如:

<code>package main

import (
\t"fmt"
\t"os"
)


func main() {
\tfmt.Println("輸入的參數為:",os.Args[1])
}/<code>

打開終端,輸入如下命令執行:

<code>go run main.go 12/<code>

這時候我們就可以看到輸出:

<code>輸入的參數為: 12/<code>

go env

在前面講go build的時候,我們使用了go env命令查看了我們當前的go環境信息。

<code>➜  hello go help env
usage: go env [var ...]

Env prints Go environment information.

By default env prints information as a shell/>(on Windows, a batch file). If one or more variable
names is given as arguments, env prints the value of
each named variable on its own line./<code>

使用go env查看我們的go環境信息,便於我們進行調試,排錯等,因為有時候我們會遇到一些莫名其妙的問題,比如本來在MAC上開發,怎麼編譯出一個Linux的可執行文件等,遇到這類問題時,先查看我們的go環境信息,看看有沒有哪裡配置錯了,一步步排錯。

go install

從其名字上我們不難猜出這個命令是做什麼的,它和go build類似,不過它可以在編譯後,把生成的可執行文件或者庫安裝到對應的目錄下,以供使用。

<code>➜  hello go help install
usage: go install [build flags] [packages]

Install compiles and installs the packages named by the import paths,
along with their dependencies./<code>

它的用法和go build差不多,如果不指定一個包名,就使用當前目錄。安裝的目錄都是約定好的,如果生成的是可執行文件,那麼安裝在$GOPATH/bin目錄下;如果是可引用的庫,那麼安裝在$GOPATH/pkg目錄下。

go get

go get命令,可以從網上下載更新指定的包以及依賴的包,並對它們進行編譯和安裝。

<code>go get github.com/spf13/cobra/<code>

以上示例,我們就可以從github上直接下載這個go庫到我們GOPATH工作空間中,以供我們使用。下載的是整個源代碼工程,並且會根據它們編譯和安裝,和執行go install類似。

go get支持大多數版本控制系統(VCS),比如我們常用的git,通過它和包依賴管理結合,我們可以在代碼中直接導入網絡上的包以供我們使用。

如果我們需要更新網絡上的一個go工程,加-u 標記即可。

<code>go get -u github.com/spf13/cobra/<code>

類似的,啟用-v標記,可以看到下載的進度以及更多的調試信息。關於go get 命令的更多用法,可以使用如下命令查看:

<code>go help get/<code>

go fmt

這是go提供的最帥的一個命令了,它可以格式化我們的源代碼的佈局和Go源代碼一樣的風格,也就是統一代碼風格,這樣我們再也不用為大括號要不要放到行尾還是另起一行,縮進是使用空格還是tab而爭論不休了,都給我們統一了。

<code>func main() { 
\tfmt.Println("輸入的參數為:", os.Args[1]) }/<code>

比如以上代碼,我們執行go fmt 格式化後,會變成如下這樣:

<code>func main() {
\tfmt.Println("輸入的參數為:", os.Args[1])
}/<code>

go fmt也是接受一個包名作為參數,如果不傳遞,則使用當前目錄。go fmt會自動格式化代碼文件並保存,它本質上其實是調用的gofmt -l -w這個命令,我們看下gofmt的使用幫助。

<code>➜  hello gofmt -h  
usage: gofmt [flags] [path ...]
-cpuprofile string
\twrite cpu profile to this file
-d\tdisplay diffs instead of rewriting files
-e\treport all errors (not just the first 10 on different lines)
-l\tlist files whose formatting differs from gofmt's
-r string
\trewrite rule (e.g., 'a[b:len(a)] -> a[b:]')
-s\tsimplify code
-w\twrite result to (source) file instead of stdout/<code>

go fmt 為我們統一了代碼風格,這樣我們在整個團隊協作中發現,所有代碼都是統一的,像一個人寫的一樣。所以我們的代碼在提交到git庫之前,一定要使用go fmt進行格式化,現在也有很多編輯器也可以在保存的時候,自動幫我們格式化代碼。

go vet

這個命令不會幫助開發人員寫代碼,但是它也很有用,因為它會幫助我們檢查我們代碼中常見的錯誤。

  1. Printf這類的函數調用時,類型匹配了錯誤的參數。
  2. 定義常用的方法時,方法簽名錯誤。
  3. 錯誤的結構標籤。
  4. 沒有指定字段名的結構字面量。
<code>package main

import (
\t"fmt"
)

func main() {
\tfmt.Printf(" 哈哈",3.14)
}/<code>

這個例子是一個明顯錯誤的例子,新手經常會犯,這裡我們忘記輸入了格式化的指令符,這種編輯器是檢查不出來的,但是如果我們使用go vet就可以幫我們檢查出這類常見的小錯誤。

<code>➜  hello go vet
main.go:8: no formatting directive in Printf call/<code>

看,提示多明顯。其使用方式和go fmt一樣,也是接受一個包名作為參數。

<code>usage: go vet [-n] [-x] [build flags] [packages]/<code>

養成在代碼提交或者測試前,使用go vet檢查代碼的好習慣,可以避免一些常見問題。

go test

該命令用於Go的單元測試,它也是接受一個包名作為參數,如果沒有指定,使用當前目錄。 go test運行的單元測試必須符合go的測試要求。

  1. 寫有單元測試的文件名,必須以_test.go結尾。
  2. 測試文件要包含若干個測試函數。
  3. 這些測試函數要以Test為前綴,還要接收一個*testing.T類型的參數。
<code>package main

import "testing"

func TestAdd(t *testing.T) {
\tif Add(1,2) == 3 {
\t\tt.Log("1+2=3")
\t}

\tif Add(1,1) == 3 {
\t\tt.Error("1+1=3")
\t}
}/<code>

這是一個單元測試,保存在main_test.go文件中,對main包裡的Add(a,b int)函數進行單元測試。 如果要運行這個單元測試,在該文件目錄下,執行go test 即可。

<code>➜  hello go test
PASS
ok \tflysnow.org/hello\t0.006s/<code>

以上是打印輸出,測試通過。更多關於go test命令的使用,請通過如下命令查看。

<code>go help test/<code>


Go語言實戰筆記(二)| Go開發工具


以上這些,主要時介紹的go這個開發工具常用的命令,熟悉了之後可以幫助我們更好的開發編碼。《Go語言實戰》中針對該部分做了一些介紹,但是比較少,只限於go build,go clean,go fmt,go vet這幾個命令,這裡進行了擴展,還加入了跨平臺編譯。

其他關於go工具提供的主題介紹,比如package是什麼等等,可以直接使用go help [topic]命令查看。

<code>Additional help topics:

\tc calling between Go and C
\tbuildmode description of build modes
\tfiletype file types
\tgopath GOPATH environment variable
\tenvironment environment variables
\timportpath import path syntax
\tpackages description of package lists
\ttestflag description of testing flags
\ttestfunc description of testing functions

Use "go help [topic]" for more information about that topic./<code>

《Go語言實戰》讀書筆記,未完待續,歡迎掃碼關注公眾號flysnow_org,第一時間看後續筆記。


分享到:


相關文章: