Go的執行原理以及Go的命令

1、Go的源碼文件

Go 的源碼文件分類:node

如上圖,分爲三類:git

一、命令源碼文件:github

聲明本身屬於 main 代碼包、包含無參數聲明和結果聲明的 main 函數。golang

命令源碼文件被安裝之後,GOPATH 若是隻有一個工做區,那麼相應的可執行文件會被存放當前工做區的 bin 文件夾下;若是有多個工做區,就會安裝到 GOBIN 指向的目錄下。算法

命令源碼文件是 Go 程序的入口。shell

同一個代碼包中最好也不要放多個命令源碼文件。多個命令源碼文件雖然能夠分開單獨 go run 運行起來,可是沒法經過 go build 和 go install。瀏覽器

咱們先打開上次課的hello目錄,而後複製helloworld.go爲helloworld2.go文件,並修改裏面的內容:安全

package mainimport "fmt"func main(){    fmt.Println("我是第二個helloworld文件")    fmt.Print("Go Go Go !!!")}複製代碼

hello目錄下有兩個go文件了,一個是helloworld.go,一個是helloworld2.go。先說明一下,在上述文件夾中放了兩個命令源碼文件,同時都聲明本身屬於 main 代碼包。ruby

打開終端,進入hello這個目錄,也能夠看到這兩個文件:bash

localhost:~ ruby cd go/src/hellolocalhost:hello ruby lshelloworld.go   helloworld2.go複製代碼

而後咱們分別執行go run命令,能夠看到兩個go文件均可以被執行:

localhost:hello ruby$ go run helloworld.goHelloWorldGo Go Go !!!localhost:hello ruby$ go run helloworld2.go我是第二個helloworld文件Go Go Go !!!複製代碼

接下來執行 go build 和 go install ,看看會發生什麼:

localhost:hello ruby$ go build # hello./helloworld2.go:3:6: main redeclared in this block previous declaration at ./helloworld.go:3:6localhost:hello ruby$ go install# hello./helloworld2.go:3:6: main redeclared in this block previous declaration at ./helloworld.go:3:6localhost:hello ruby$ 複製代碼

運行效果圖:

這也就證實了多個命令源碼文件雖然能夠分開單獨 go run 運行起來,可是沒法經過 go build 和 go install。

同理,若是命令源碼文件和庫源碼文件也會出現這樣的問題,庫源碼文件不能經過 go build 和 go install 這種常規的方法編譯和安裝。具體例子和上述相似,這裏就再也不貼代碼了。

因此命令源碼文件應該是被單獨放在一個代碼包中。

二、庫源碼文件

庫源碼文件就是不具有命令源碼文件上述兩個特徵的源碼文件。存在於某個代碼包中的普通的源碼文件。

庫源碼文件被安裝後,相應的歸檔文件(.a 文件)會被存放到當前工做區的 pkg 的平臺相關目錄下。

三、測試源碼文件

名稱以 _test.go 爲後綴的代碼文件,而且必須包含 Test 或者 Benchmark 名稱前綴的函數:

func TestXXX( t *testing.T) {​}複製代碼

名稱以 Test 爲名稱前綴的函數,只能接受 *testing.T 的參數,這種測試函數是功能測試函數。

func BenchmarkXXX( b *testing.B) {​}​複製代碼

名稱以 Benchmark 爲名稱前綴的函數,只能接受 *testing.B 的參數,這種測試函數是性能測試函數。

如今答案就很明顯了:

命令源碼文件是能夠單獨運行的。可使用 go run 命令直接運行,也能夠經過 go build 或 go install 命令獲得相應的可執行文件。因此命令源碼文件是能夠在機器的任何目錄下運行的。

舉個栗子:

好比平時咱們在 LeetCode 上刷算法題,這時候寫的就是一個程序,這就是命令源碼文件,能夠在電腦的任意一個文件夾新建一個 go 文件就能夠開始刷題了,寫完就能夠運行,對比執行結果,答案對了就能夠提交代碼。

可是公司項目裏面的代碼就不能這樣了,只能存放在 GOPATH 目錄下。由於公司項目不可能只有命令源碼文件的,確定是包含庫源碼文件,甚至包含測試源碼文件的。

2、Go的命令

目前Go的最新版1.12裏面基本命令有如下17個。

咱們能夠打開終端輸入:go help便可看到Go的這些命令以及簡介。

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複製代碼

其中和編譯相關的有build、get、install、run這4個。接下來就依次看看這四個的做用。

在詳細分析這4個命令以前,先羅列一下通用的命令標記,如下這些命令均可適用的:

名稱 說明
-a 用於強制從新編譯全部涉及的 Go 語言代碼包(包括 Go 語言標準庫中的代碼包),即便它們已是最新的了。該標記可讓咱們有機會經過改動底層的代碼包作一些實驗。
-n 使命令僅打印其執行過程當中用到的全部命令,而不去真正執行它們。若是不僅想查看或者驗證命令的執行過程,而不想改變任何東西,使用它正好合適。
-race 用於檢測並報告指定 Go 語言程序中存在的數據競爭問題。當用 Go 語言編寫併發程序的時候,這是很重要的檢測手段之一。
-v 用於打印命令執行過程當中涉及的代碼包。這必定包括咱們指定的目標代碼包,而且有時還會包括該代碼包直接或間接依賴的那些代碼包。這會讓你知道哪些代碼包被執行過了。
-work 用於打印命令執行時生成和使用的臨時工做目錄的名字,且命令執行完成後不刪除它。這個目錄下的文件可能會對你有用,也能夠從側面瞭解命令的執行過程。若是不添加此標記,那麼臨時工做目錄會在命令執行完畢前刪除。
-x 使命令打印其執行過程當中用到的全部命令,並同時執行它們。

1. go run

專門用來運行命令源碼文件的命令,注意,這個命令不是用來運行全部 Go 的源碼文件的!

go run 命令只能接受一個命令源碼文件以及若干個庫源碼文件(必須同屬於 main 包)做爲文件參數,且不能接受測試源碼文件。它在執行時會檢查源碼文件的類型。若是參數中有多個或者沒有命令源碼文件,那麼 go run 命令就只會打印錯誤提示信息並退出,而不會繼續執行。

這個命令具體幹了些什麼事情呢?來分析分析,咱們先從新建立一個新文件:mytest.go,並加入如下代碼:

package mainimport "fmt"func main(){    fmt.Println("HelloWorld")    fmt.Println("你好,Go!!!")}複製代碼

執行go run 配合-n:

localhost:hello ruby$ go run -n mytest.go ​## command-line-arguments#​mkdir -p $WORK/b001/cat >$WORK/b001/importcfg << 'EOF' # internal# import configpackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.apackagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.aEOFcd /Users/ruby/go/src/hello/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main -complete -buildid ieg41NOobNF0eqq3xgnP/ieg41NOobNF0eqq3xgnP -dwarf=false -goversion go1.12.1 -D _/Users/ruby/go/src/hello -importcfg $WORK/b001/importcfg -pack -c=4 ./mytest.go/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internalcat >$WORK/b001/importcfg.link << 'EOF' # internal... # 此處省略EOFmkdir -p $WORK/b001/exe/cd ./usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/mytest -importcfg $WORK/b001/importcfg.link -s -w -buildmode=exe -buildid=vpgT856LhbZPXp6WeHib/ieg41NOobNF0eqq3xgnP/ieg41NOobNF0eqq3xgnP/vpgT856LhbZPXp6WeHib -extld=clang $WORK/b001/_pkg_.a$WORK/b001/exe/mytestlocalhost:hello ruby$ ​複製代碼

運行效果圖:

這裏能夠看到建立了兩個臨時文件夾 b001 和 exe,先執行了 compile 命令,而後 link,生成了歸檔文件.a 和 最終可執行文件,最終的可執行文件放在 exe 文件夾裏面。命令的最後一步就是執行了可執行文件。

總結一下以下圖:

舉個例子,生成的臨時文件能夠用go run -work看到,好比當前生成的臨時文件夾是以下的路徑:

localhost:hello ruby$ go run -work mytest.go WORK=/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build593750496HelloWorld你好,Go!!!localhost:hello ruby$ 複製代碼

咱們進入:/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build593750496目錄,能夠看到以下目錄結構:

能夠看到,最終go run命令是生成了2個文件,一個是歸檔文件,一個是可執行文件。

go run 命令在第二次執行的時候,若是發現導入的代碼包沒有發生變化,那麼 go run 不會再次編譯這個導入的代碼包。直接靜態連接進來。

localhost:hello ruby$ go run -n mytest.go mkdir -p $WORK/b001/cat >$WORK/b001/importcfg.link << 'EOF' # internalpackagefile command-line-arguments=/Users/ruby/Library/Caches/go-build/6b/6b9577027c8da20b0ae6da790267f558b3b71eea1feb44039fb933b35eaef6f9-dpackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a...EOFmkdir -p $WORK/b001/exe/cd ./usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/mytest -importcfg $WORK/b001/importcfg.link -s -w -buildmode=exe -buildid=goiqf_1cemqljgOYzSRA/ieg41NOobNF0eqq3xgnP/MVbHdxOky1BGK6Aq_4bM/goiqf_1cemqljgOYzSRA -extld=clang /Users/ruby/Library/Caches/go-build/6b/6b9577027c8da20b0ae6da790267f558b3b71eea1feb44039fb933b35eaef6f9-d$WORK/b001/exe/mytestlocalhost:hello ruby$ ​複製代碼

2. go build

go build 命令主要是用於測試編譯。在包的編譯過程當中,如有必要,會同時編譯與之相關聯的包。

  1. 若是是普通包,當你執行go build命令後,不會產生任何文件。

  2. 若是是main包,當只執行go build命令後,會在當前目錄下生成一個可執行文件。若是須要在$GOPATH/bin目錄下生成相應的exe文件,須要執行go install 或者使用 go build -o 路徑/可執行文件。

  3. 若是某個文件夾下有多個文件,而你只想編譯其中某一個文件,能夠在 go build 以後加上文件名,例如 go build a.go;go build 命令默認會編譯當前目錄下的全部go文件。

  4. 你也能夠指定編譯輸出的文件名。好比,咱們能夠指定go build -o 可執行文件名,默認狀況是你的package名(非main包),或者是第一個源文件的文件名(main包)。

  5. go build 會忽略目錄下以」_」或者」.」開頭的go文件。

  6. 若是你的源代碼針對不一樣的操做系統須要不一樣的處理,那麼你能夠根據不一樣的操做系統後綴來命名文件。

當代碼包中有且僅有一個命令源碼文件的時候,在文件夾所在目錄中執行 go build 命令,會在該目錄下生成一個與目錄同名的可執行文件。

// 假設當前文件夾名叫 hellolocalhost:hello ruby$ pwd/Users/ruby/go/src/hellolocalhost:hello ruby$ lshelloworld.golocalhost:hello ruby$ go buildlocalhost:hello ruby$ lshello       helloworld.golocalhost:hello ruby$ 複製代碼

因而在當前目錄直接生成了以當前文件夾爲名的可執行文件( 在 Mac 平臺下是 Unix executable 文件,在 Windows 平臺下是 exe 文件)

可是這種狀況下,若是使用 go install 命令,若是 GOPATH 裏面只有一個工做區,就會在當前工做區的 bin 目錄下生成相應的可執行文件。若是 GOPATH 下有多個工做區,則是在 GOBIN 下生成對應的可執行文件。

localhost:hello ruby$ go installgo install hello: open /usr/local/go/bin/hello: permission deniedlocalhost:hello ruby$ 複製代碼

這個問題是由於它須要建立bin目錄,而後把可剛纔的可執行文件放進去,而目前咱們在gopath下尚未bin目錄,那麼就須要先建立這個文件,而普通用戶沒有直接建立文件夾的權限,這個和Go語言的命令是沒有關係的。咱們能夠加上sodu 來執行這個命令,表示使用管理員的身份執行,而後輸入密碼,那麼就能夠建立bin這個文件夾了。

再次執行:

localhost:hello ruby$ sudo go installPassword:localhost:hello ruby$ ​複製代碼

執行完 go install 會發現可執行文件不見了!去哪裏了呢?實際上是被移動到了 bin 目錄下了(若是 GOPATH 下有多個工做區,就會放在GOBIN 目錄下)。

查看目錄:

那 go build 和 go install 究竟幹了些什麼呢?

先來講說 go build。go build 用於編譯咱們指定的源碼文件或代碼包以及它們的依賴包。可是注意若是用來編譯非命令源碼文件,即庫源碼文件,go build 執行完是不會產生任何結果的。這種狀況下,go build 命令只是檢查庫源碼文件的有效性,只會作檢查性的編譯,而不會輸出任何結果文件。

go build 編譯命令源碼文件,則會在該命令的執行目錄中生成一個可執行文件,上面的例子也印證了這個過程。

go build 後面不追加目錄路徑的話,它就把當前目錄做爲代碼包並進行編譯。go build 命令後面若是跟了代碼包導入路徑做爲參數,那麼該代碼包及其依賴都會被編譯。

go build 命令究竟作了些什麼呢?咱們能夠執行-n這個命令來查看:

localhost:hello ruby$ go build -n​## hello#​mkdir -p $WORK/b001/cat >$WORK/b001/importcfg << 'EOF' # internal# import configpackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.apackagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.aEOFcd /Users/ruby/go/src/hello/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main -complete -buildid PXDetO1R1NhLFMK5QGUc/PXDetO1R1NhLFMK5QGUc -goversion go1.12.1 -D "" -importcfg $WORK/b001/importcfg -pack -c=4 ./helloworld.go/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internalcat >$WORK/b001/importcfg.link << 'EOF' # internalpackagefile hello=$WORK/b001/_pkg_.a...EOFmkdir -p $WORK/b001/exe/cd ./usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=diTh1q6kcbGRIX3aj3mU/PXDetO1R1NhLFMK5QGUc/PXDetO1R1NhLFMK5QGUc/diTh1q6kcbGRIX3aj3mU -extld=clang $WORK/b001/_pkg_.a/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internalmv $WORK/b001/exe/a.out hellolocalhost:hello ruby$ ​複製代碼

能夠看到,執行過程和 go run 大致相同,惟一不一樣的就是在最後一步,go run 是執行了可執行文件,可是 go build 命令,只是把庫源碼文件編譯了一遍,而後把可執行文件移動到了當前目錄的文件夾中。

總結一下以下圖:

3. go install

go install 命令是用來編譯並安裝代碼包或者源碼文件的。

go install 命令在內部實際上分紅了兩步操做:第一步是生成結果文件(可執行文件或者.a包),第二步會把編譯好的結果移到$GOPATH/pkg或者​$GOPATH/bin

可執行文件: 通常是 go install 帶main函數的go文件產生的,有函數入口,全部能夠直接運行。

.a應用包: 通常是 go install 不包含main函數的go文件產生的,沒有函數入口,只能被調用。

go install 用於編譯並安裝指定的代碼包及它們的依賴包。當指定的代碼包的依賴包尚未被編譯和安裝時,該命令會先去處理依賴包。與 go build 命令同樣,傳給 go install 命令的代碼包參數應該以導入路徑的形式提供。而且,go build 命令的絕大多數標記也均可以用於 實際上,go install 命令只比 go build 命令多作了一件事,即:安裝編譯後的結果文件到指定目錄。

安裝代碼包會在當前工做區的 pkg 的平臺相關目錄下生成歸檔文件(即 .a 文件)。 安裝命令源碼文件會在當前工做區的 bin 目錄(若是 GOPATH 下有多個工做區,就會放在 GOBIN 目錄下)生成可執行文件。

一樣,go install 命令若是後面不追加任何參數,它會把當前目錄做爲代碼包並安裝。這和 go build 命令是徹底同樣的。

go install 命令後面若是跟了代碼包導入路徑做爲參數,那麼該代碼包及其依賴都會被安裝。

go install 命令後面若是跟了命令源碼文件以及相關庫源碼文件做爲參數的話,只有這些文件會被編譯並安裝。

go install 命令究竟作了些什麼呢?

localhost:hello ruby$ go install -n​## hello#​mkdir -p $WORK/b001/cat >$WORK/b001/importcfg << 'EOF' # internal# import configpackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.apackagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.aEOFcd /Users/ruby/go/src/hello/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main -complete -buildid E1CTs4eXkD5M28s_FQXT/E1CTs4eXkD5M28s_FQXT -goversion go1.12.1 -D "" -importcfg $WORK/b001/importcfg -pack -c=4 ./helloworld.go/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internalcat >$WORK/b001/importcfg.link << 'EOF' # internalpackagefile hello=$WORK/b001/_pkg_.apackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a...EOFmkdir -p $WORK/b001/exe/cd ./usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=FJ6kJTmN9rcWcwLhqfiQ/E1CTs4eXkD5M28s_FQXT/E1CTs4eXkD5M28s_FQXT/FJ6kJTmN9rcWcwLhqfiQ -extld=clang $WORK/b001/_pkg_.a/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internalmkdir -p /usr/local/go/bin/mv $WORK/b001/exe/a.out /usr/local/go/bin/hellolocalhost:hello ruby$ ​複製代碼

前面幾步依舊和 go run 、go build 徹底一致,只是最後一步的差異,go install 會把命令源碼文件安裝到當前工做區的 bin 目錄(若是 GOPATH 下有多個工做區,就會放在 GOBIN 目錄下)。若是是庫源碼文件,就會被安裝到當前工做區的 pkg 的平臺相關目錄下。

總結一下以下圖:

在安裝多個庫源碼文件時有可能遇到以下的問題:

localhost:hello ruby$  go install envir.go fpath.go ipath.go pnode.go util.gogo install: no install location for .go files listed on command line (GOBIN not set)複製代碼

並且,在咱們爲環境變量 GOBIN 設置了正確的值以後,這個錯誤提示信息仍然會出現。這是由於,只有在安裝命令源碼文件的時候,命令程序纔會將環境變量 GOBIN 的值做爲結果文件的存放目錄。而在安裝庫源碼文件時,在命令程序內部的表明結果文件存放目錄路徑的那個變量不會被賦值。最後,命令程序會發現它依然是個無效的空值。因此,命令程序會一樣返回一個關於「無安裝位置」的錯誤。這就引出一個結論,咱們只能使用安裝代碼包的方式來安裝庫源碼文件,而不能在 go install 命令羅列並安裝它們。另外,go install 命令目前沒法接受標記-o以自定義結果文件的存放位置。這也從側面說明了 go install 命令不支持針對庫源碼文件的安裝操做。

4. go get

go get 命令用於從遠程代碼倉庫(好比 Github )上下載並安裝代碼包。注意,go get 命令會把當前的代碼包下載到 $GOPATH 中的第一個工做區的 src 目錄中,並安裝。

使用 go get 下載第三方包的時候,依舊會下載到 $GOPATH 的第一個工做空間,而非 vendor 目錄。當前工做鏈中並無真正意義上的包依賴管理,不過好在有很多第三方工具可選。

若是在 go get 下載過程當中加入-d 標記,那麼下載操做只會執行下載動做,而不執行安裝動做。好比有些很是特殊的代碼包在安裝過程當中須要有特殊的處理,因此咱們須要先下載下來,因此就會用到-d 標記。

還有一個頗有用的標記是-u標記,加上它能夠利用網絡來更新已有的代碼包及其依賴包。若是已經下載過一個代碼包,可是這個代碼包又有更新了,那麼這時候能夠直接用-u標記來更新本地的對應的代碼包。若是不加這個-u標記,執行 go get 一個已有的代碼包,會發現命令什麼都不執行。只有加了-u標記,命令會去執行 git pull 命令拉取最新的代碼包的最新版本,下載並安裝。

命令 go get 還有一個很值得稱道的功能——智能下載。在使用它檢出或更新代碼包以後,它會尋找與本地已安裝 Go 語言的版本號相對應的標籤(tag)或分支(branch)。好比,本機安裝 Go 語言的版本是1.x,那麼 go get 命令會在該代碼包的遠程倉庫中尋找名爲 「go1」 的標籤或者分支。若是找到指定的標籤或者分支,則將本地代碼包的版本切換到此標籤或者分支。若是沒有找到指定的標籤或者分支,則將本地代碼包的版本切換到主幹的最新版本。

go get 經常使用的一些標記以下:

標記名稱 標記描述
-d 讓命令程序只執行下載動做,而不執行安裝動做。
-f 僅在使用-u標記時纔有效。該標記會讓命令程序忽略掉對已下載代碼包的導入路徑的檢查。若是下載並安裝的代碼包所屬的項目是你從別人那裏 Fork 過來的,那麼這樣作就尤其重要了。
-fix 讓命令程序在下載代碼包後先執行修正動做,然後再進行編譯和安裝。
-insecure 容許命令程序使用非安全的 scheme(如 HTTP )去下載指定的代碼包。若是你用的代碼倉庫(如公司內部的 Gitlab )沒有HTTPS 支持,能夠添加此標記。請在肯定安全的狀況下使用它。
-t 讓命令程序同時下載並安裝指定的代碼包中的測試源碼文件中依賴的代碼包。
-u 讓命令利用網絡來更新已有代碼包及其依賴包。默認狀況下,該命令只會從網絡上下載本地不存在的代碼包,而不會更新已有的代碼包。

go get 命令究竟作了些什麼呢?咱們仍是來打印一下每一步的執行過程。

localhost:hello ruby$ go get -x github.com/go-errors/errorscd .git clone https://github.com/go-errors/errors /Users/ruby/go/src/github.com/go-errors/errorscd /Users/ruby/go/src/github.com/go-errors/errorsgit submodule update --init --recursivecd /Users/ruby/go/src/github.com/go-errors/errorsgit show-refcd /Users/ruby/go/src/github.com/go-errors/errorsgit submodule update --init --recursiveWORK=/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build188558329localhost:hello ruby$ 複製代碼

效果圖:

這裏能夠很明顯的看到,執行完 go get 命令之後,會調用 git clone 方法下載源碼,並編譯,最終會把庫源碼文件編譯成歸檔文件安裝到 pkg 對應的相關平臺目錄下。

總結一下以下圖:

5. 其餘命令

go clean

go clean 命令是用來移除當前源碼包裏面編譯生成的文件,這些文件包括

  • _obj/ 舊的object目錄,由Makefiles遺留

  • _test/ 舊的test目錄,由Makefiles遺留

  • _testmain.go 舊的gotest文件,由Makefiles遺留

  • test.out 舊的test記錄,由Makefiles遺留

  • build.out 舊的test記錄,由Makefiles遺留

  • *.[568ao] object文件,由Makefiles遺留

  • DIR(.exe) 由 go build 產生

  • DIR.test(.exe) 由 go test -c 產生

  • MAINFILE(.exe) 由 go build MAINFILE.go產生

go fmt

go fmt 命令主要是用來幫你格式化所寫好的代碼文件。

好比咱們寫了一個格式很糟糕的 test.go 文件,咱們只須要使用 fmt go test.go 命令,就可讓go幫咱們格式化咱們的代碼文件。可是咱們通常不多使用這個命令,由於咱們的開發工具通常都帶有保存時自動格式化功能,這個功能底層其實就是調用了 go fmt 命令而已。

使用go fmt命令,更多時候是用gofmt,並且須要參數-w,不然格式化結果不會寫入文件。gofmt -w src,能夠格式化整個項目。

go test

go test 命令,會自動讀取源碼目錄下面名爲*_test.go的文件,生成並運行測試用的可執行文件。默認的狀況下,不須要任何的參數,它會自動把你源碼包下面全部test文件測試完畢,固然你也能夠帶上參數,詳情請參考go help testflag

go doc

go doc 命令其實就是一個很強大的文檔工具。

如何查看相應package的文檔呢? 例如builtin包,那麼執行go doc builtin;若是是http包,那麼執行go doc net/http;查看某一個包裏面的函數,那麼執行go doc fmt Printf;也能夠查看相應的代碼,執行go doc -src fmt Printf;

# 查看net/http包localhost:hello ruby$ go doc net/http# 查看time包localhost:hello ruby$ go doc time# 查看某個包裏的指定函數localhost:hello ruby$ go doc fmt Printf複製代碼

經過命令在命令行執行 go doc -http=:端口號,好比godoc -http=:8080。而後在瀏覽器中打開127.0.0.1:8080,你將會看到一個golang.org的本地copy版本,經過它你能夠查詢pkg文檔等其它內容。若是你設置了GOPATH,在pkg分類下,不但會列出標準包的文檔,還會列出你本地GOPATH中全部項目的相關文檔,這對於常常被限制訪問的用戶來講是一個不錯的選擇。

localhost:hello ruby$ godoc -http=:9527複製代碼

go fix 用來修復之前老版本的代碼到新版本,例如go1以前老版本的代碼轉化到go1

go version 查看go當前的版本

go env 查看當前go的環境變量

go list 列出當前所有安裝的package

相關文章
相關標籤/搜索