Go 語言 工具

2023-03-14 16:59 更新

原文鏈接:https://gopl-zh.github.io/ch10/ch10-07.html


10.7. 工具

本章剩下的部分將討論Go語言工具箱的具體功能,包括如何下載、格式化、構(gòu)建、測(cè)試和安裝Go語言編寫的程序。

Go語言的工具箱集合了一系列功能的命令集。它可以看作是一個(gè)包管理器(類似于Linux中的apt和rpm工具),用于包的查詢、計(jì)算包的依賴關(guān)系、從遠(yuǎn)程版本控制系統(tǒng)下載它們等任務(wù)。它也是一個(gè)構(gòu)建系統(tǒng),計(jì)算文件的依賴關(guān)系,然后調(diào)用編譯器、匯編器和鏈接器構(gòu)建程序,雖然它故意被設(shè)計(jì)成沒有標(biāo)準(zhǔn)的make命令那么復(fù)雜。它也是一個(gè)單元測(cè)試和基準(zhǔn)測(cè)試的驅(qū)動(dòng)程序,我們將在第11章討論測(cè)試話題。

Go語言工具箱的命令有著類似“瑞士軍刀”的風(fēng)格,帶著一打的子命令,有一些我們經(jīng)常用到,例如get、run、build和fmt等。你可以運(yùn)行g(shù)o或go help命令查看內(nèi)置的幫助文檔,為了查詢方便,我們列出了最常用的命令:

$ go
...
    build            compile packages and dependencies
    clean            remove object files
    doc              show documentation for package or symbol
    env              print Go environment information
    fmt              run gofmt on package sources
    get              download and install packages and dependencies
    install          compile and install packages and dependencies
    list             list packages
    run              compile and run Go program
    test             test packages
    version          print Go version
    vet              run go tool vet on packages

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

為了達(dá)到零配置的設(shè)計(jì)目標(biāo),Go語言的工具箱很多地方都依賴各種約定。例如,根據(jù)給定的源文件的名稱,Go語言的工具可以找到源文件對(duì)應(yīng)的包,因?yàn)槊總€(gè)目錄只包含了單一的包,并且包的導(dǎo)入路徑和工作區(qū)的目錄結(jié)構(gòu)是對(duì)應(yīng)的。給定一個(gè)包的導(dǎo)入路徑,Go語言的工具可以找到與之對(duì)應(yīng)的存儲(chǔ)著實(shí)體文件的目錄。它還可以根據(jù)導(dǎo)入路徑找到存儲(chǔ)代碼的倉庫的遠(yuǎn)程服務(wù)器URL。

10.7.1. 工作區(qū)結(jié)構(gòu)

對(duì)于大多數(shù)的Go語言用戶,只需要配置一個(gè)名叫GOPATH的環(huán)境變量,用來指定當(dāng)前工作目錄即可。當(dāng)需要切換到不同工作區(qū)的時(shí)候,只要更新GOPATH就可以了。例如,我們?cè)诰帉懕緯鴷r(shí)將GOPATH設(shè)置為$HOME/gobook

$ export GOPATH=$HOME/gobook
$ go get gopl.io/...

當(dāng)你用前面介紹的命令下載本書全部的例子源碼之后,你的當(dāng)前工作區(qū)的目錄結(jié)構(gòu)應(yīng)該是這樣的:

GOPATH/
    src/
        gopl.io/
            .git/
            ch1/
                helloworld/
                    main.go
                dup/
                    main.go
                ...
        golang.org/x/net/
            .git/
            html/
                parse.go
                node.go
                ...
    bin/
        helloworld
        dup
    pkg/
        darwin_amd64/
        ...

GOPATH對(duì)應(yīng)的工作區(qū)目錄有三個(gè)子目錄。其中src子目錄用于存儲(chǔ)源代碼。每個(gè)包被保存在與$GOPATH/src的相對(duì)路徑為包導(dǎo)入路徑的子目錄中,例如gopl.io/ch1/helloworld相對(duì)應(yīng)的路徑目錄。我們看到,一個(gè)GOPATH工作區(qū)的src目錄中可能有多個(gè)獨(dú)立的版本控制系統(tǒng),例如gopl.io和golang.org分別對(duì)應(yīng)不同的Git倉庫。其中pkg子目錄用于保存編譯后的包的目標(biāo)文件,bin子目錄用于保存編譯后的可執(zhí)行程序,例如helloworld可執(zhí)行程序。

第二個(gè)環(huán)境變量GOROOT用來指定Go的安裝目錄,還有它自帶的標(biāo)準(zhǔn)庫包的位置。GOROOT的目錄結(jié)構(gòu)和GOPATH類似,因此存放fmt包的源代碼對(duì)應(yīng)目錄應(yīng)該為$GOROOT/src/fmt。用戶一般不需要設(shè)置GOROOT,默認(rèn)情況下Go語言安裝工具會(huì)將其設(shè)置為安裝的目錄路徑。

其中go env命令用于查看Go語言工具涉及的所有環(huán)境變量的值,包括未設(shè)置環(huán)境變量的默認(rèn)值。GOOS環(huán)境變量用于指定目標(biāo)操作系統(tǒng)(例如android、linux、darwin或windows),GOARCH環(huán)境變量用于指定處理器的類型,例如amd64、386或arm等。雖然GOPATH環(huán)境變量是唯一必須要設(shè)置的,但是其它環(huán)境變量也會(huì)偶爾用到。

$ go env
GOPATH="/home/gopher/gobook"
GOROOT="/usr/local/go"
GOARCH="amd64"
GOOS="darwin"
...

10.7.2. 下載包

使用Go語言工具箱的go命令,不僅可以根據(jù)包導(dǎo)入路徑找到本地工作區(qū)的包,甚至可以從互聯(lián)網(wǎng)上找到和更新包。

使用命令go get可以下載一個(gè)單一的包或者用...下載整個(gè)子目錄里面的每個(gè)包。Go語言工具箱的go命令同時(shí)計(jì)算并下載所依賴的每個(gè)包,這也是前一個(gè)例子中g(shù)olang.org/x/net/html自動(dòng)出現(xiàn)在本地工作區(qū)目錄的原因。

一旦go get命令下載了包,然后就是安裝包或包對(duì)應(yīng)的可執(zhí)行的程序。我們將在下一節(jié)再關(guān)注它的細(xì)節(jié),現(xiàn)在只是展示整個(gè)下載過程是如何的簡(jiǎn)單。第一個(gè)命令是獲取golint工具,它用于檢測(cè)Go源代碼的編程風(fēng)格是否有問題。第二個(gè)命令是用golint命令對(duì)2.6.2節(jié)的gopl.io/ch2/popcount包代碼進(jìn)行編碼風(fēng)格檢查。它友好地報(bào)告了忘記了包的文檔:

$ go get github.com/golang/lint/golint
$ $GOPATH/bin/golint gopl.io/ch2/popcount
src/gopl.io/ch2/popcount/main.go:1:1:
  package comment should be of the form "Package popcount ..."

go get命令支持當(dāng)前流行的托管網(wǎng)站GitHub、Bitbucket和Launchpad,可以直接向它們的版本控制系統(tǒng)請(qǐng)求代碼。對(duì)于其它的網(wǎng)站,你可能需要指定版本控制系統(tǒng)的具體路徑和協(xié)議,例如 Git或Mercurial。運(yùn)行go help importpath獲取相關(guān)的信息。

go get命令獲取的代碼是真實(shí)的本地存儲(chǔ)倉庫,而不僅僅只是復(fù)制源文件,因此你依然可以使用版本管理工具比較本地代碼的變更或者切換到其它的版本。例如golang.org/x/net包目錄對(duì)應(yīng)一個(gè)Git倉庫:

$ cd $GOPATH/src/golang.org/x/net
$ git remote -v
origin  https://go.googlesource.com/net (fetch)
origin  https://go.googlesource.com/net (push)

需要注意的是導(dǎo)入路徑含有的網(wǎng)站域名和本地Git倉庫對(duì)應(yīng)遠(yuǎn)程服務(wù)地址并不相同,真實(shí)的Git地址是go.googlesource.com。這其實(shí)是Go語言工具的一個(gè)特性,可以讓包用一個(gè)自定義的導(dǎo)入路徑,但是真實(shí)的代碼卻是由更通用的服務(wù)提供,例如googlesource.com或github.com。因?yàn)轫撁?https://golang.org/x/net/html 包含了如下的元數(shù)據(jù),它告訴Go語言的工具當(dāng)前包真實(shí)的Git倉庫托管地址:

$ go build gopl.io/ch1/fetch
$ ./fetch https://golang.org/x/net/html | grep go-import
<meta name="go-import"
      content="golang.org/x/net git https://go.googlesource.com/net">

如果指定-u命令行標(biāo)志參數(shù),go get命令將確保所有的包和依賴的包的版本都是最新的,然后重新編譯和安裝它們。如果不包含該標(biāo)志參數(shù)的話,而且如果包已經(jīng)在本地存在,那么代碼將不會(huì)被自動(dòng)更新。

go get -u命令只是簡(jiǎn)單地保證每個(gè)包是最新版本,如果是第一次下載包則是比較方便的;但是對(duì)于發(fā)布程序則可能是不合適的,因?yàn)楸镜爻绦蚩赡苄枰獙?duì)依賴的包做精確的版本依賴管理。通常的解決方案是使用vendor的目錄用于存儲(chǔ)依賴包的固定版本的源代碼,對(duì)本地依賴的包的版本更新也是謹(jǐn)慎和持續(xù)可控的。在Go1.5之前,一般需要修改包的導(dǎo)入路徑,所以復(fù)制后golang.org/x/net/html導(dǎo)入路徑可能會(huì)變?yōu)間opl.io/vendor/golang.org/x/net/html。最新的Go語言命令已經(jīng)支持vendor特性,但限于篇幅這里并不討論vendor的具體細(xì)節(jié)。不過可以通過go help gopath命令查看Vendor的幫助文檔。

(譯注:墻內(nèi)用戶在上面這些命令的基礎(chǔ)上,還需要學(xué)習(xí)用翻墻來go get。)

練習(xí) 10.3: 從 http://gopl.io/ch1/helloworld?go-get=1 獲取內(nèi)容,查看本書的代碼的真實(shí)托管的網(wǎng)址(go get請(qǐng)求HTML頁面時(shí)包含了go-get參數(shù),以區(qū)別普通的瀏覽器請(qǐng)求)。

10.7.3. 構(gòu)建包

go build命令編譯命令行參數(shù)指定的每個(gè)包。如果包是一個(gè)庫,則忽略輸出結(jié)果;這可以用于檢測(cè)包是可以正確編譯的。如果包的名字是main,go build將調(diào)用鏈接器在當(dāng)前目錄創(chuàng)建一個(gè)可執(zhí)行程序;以導(dǎo)入路徑的最后一段作為可執(zhí)行程序的名字。

由于每個(gè)目錄只包含一個(gè)包,因此每個(gè)對(duì)應(yīng)可執(zhí)行程序或者叫Unix術(shù)語中的命令的包,會(huì)要求放到一個(gè)獨(dú)立的目錄中。這些目錄有時(shí)候會(huì)放在名叫cmd目錄的子目錄下面,例如用于提供Go文檔服務(wù)的golang.org/x/tools/cmd/godoc命令就是放在cmd子目錄(§10.7.4)。

每個(gè)包可以由它們的導(dǎo)入路徑指定,就像前面看到的那樣,或者用一個(gè)相對(duì)目錄的路徑名指定,相對(duì)路徑必須以...開頭。如果沒有指定參數(shù),那么默認(rèn)指定為當(dāng)前目錄對(duì)應(yīng)的包。下面的命令用于構(gòu)建同一個(gè)包,雖然它們的寫法各不相同:

$ cd $GOPATH/src/gopl.io/ch1/helloworld
$ go build

或者:

$ cd anywhere
$ go build gopl.io/ch1/helloworld

或者:

$ cd $GOPATH
$ go build ./src/gopl.io/ch1/helloworld

但不能這樣:

$ cd $GOPATH
$ go build src/gopl.io/ch1/helloworld
Error: cannot find package "src/gopl.io/ch1/helloworld".

也可以指定包的源文件列表,這一般只用于構(gòu)建一些小程序或做一些臨時(shí)性的實(shí)驗(yàn)。如果是main包,將會(huì)以第一個(gè)Go源文件的基礎(chǔ)文件名作為最終的可執(zhí)行程序的名字。

$ cat quoteargs.go
package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Printf("%q\n", os.Args[1:])
}
$ go build quoteargs.go
$ ./quoteargs one "two three" four\ five
["one" "two three" "four five"]

特別是對(duì)于這類一次性運(yùn)行的程序,我們希望盡快的構(gòu)建并運(yùn)行它。go run命令實(shí)際上是結(jié)合了構(gòu)建和運(yùn)行的兩個(gè)步驟:

$ go run quoteargs.go one "two three" four\ five
["one" "two three" "four five"]

(譯注:其實(shí)也可以偷懶,直接go run *.go)

第一行的參數(shù)列表中,第一個(gè)不是以.go結(jié)尾的將作為可執(zhí)行程序的參數(shù)運(yùn)行。

默認(rèn)情況下,go build命令構(gòu)建指定的包和它依賴的包,然后丟棄除了最后的可執(zhí)行文件之外所有的中間編譯結(jié)果。依賴分析和編譯過程雖然都是很快的,但是隨著項(xiàng)目增加到幾十個(gè)包和成千上萬行代碼,依賴關(guān)系分析和編譯時(shí)間的消耗將變的可觀,有時(shí)候可能需要幾秒種,即使這些依賴項(xiàng)沒有改變。

go install命令和go build命令很相似,但是它會(huì)保存每個(gè)包的編譯成果,而不是將它們都丟棄。被編譯的包會(huì)被保存到$GOPATH/pkg目錄下,目錄路徑和 src目錄路徑對(duì)應(yīng),可執(zhí)行程序被保存到$GOPATH/bin目錄。(很多用戶會(huì)將$GOPATH/bin添加到可執(zhí)行程序的搜索列表中。)還有,go install命令和go build命令都不會(huì)重新編譯沒有發(fā)生變化的包,這可以使后續(xù)構(gòu)建更快捷。為了方便編譯依賴的包,go build -i命令將安裝每個(gè)目標(biāo)所依賴的包。

因?yàn)榫幾g對(duì)應(yīng)不同的操作系統(tǒng)平臺(tái)和CPU架構(gòu),go install命令會(huì)將編譯結(jié)果安裝到GOOS和GOARCH對(duì)應(yīng)的目錄。例如,在Mac系統(tǒng),golang.org/x/net/html包將被安裝到$GOPATH/pkg/darwin_amd64目錄下的golang.org/x/net/html.a文件。

針對(duì)不同操作系統(tǒng)或CPU的交叉構(gòu)建也是很簡(jiǎn)單的。只需要設(shè)置好目標(biāo)對(duì)應(yīng)的GOOS和GOARCH,然后運(yùn)行構(gòu)建命令即可。下面交叉編譯的程序?qū)⑤敵鏊诰幾g時(shí)的操作系統(tǒng)和CPU類型:

gopl.io/ch10/cross

func main() {
    fmt.Println(runtime.GOOS, runtime.GOARCH)
}

下面以64位和32位環(huán)境分別編譯和執(zhí)行:

$ go build gopl.io/ch10/cross
$ ./cross
darwin amd64
$ GOARCH=386 go build gopl.io/ch10/cross
$ ./cross
darwin 386

有些包可能需要針對(duì)不同平臺(tái)和處理器類型使用不同版本的代碼文件,以便于處理底層的可移植性問題或?yàn)橐恍┨囟ùa提供優(yōu)化。如果一個(gè)文件名包含了一個(gè)操作系統(tǒng)或處理器類型名字,例如net_linux.go或asm_amd64.s,Go語言的構(gòu)建工具將只在對(duì)應(yīng)的平臺(tái)編譯這些文件。還有一個(gè)特別的構(gòu)建注釋參數(shù)可以提供更多的構(gòu)建過程控制。例如,文件中可能包含下面的注釋:

// +build linux darwin

在包聲明和包注釋的前面,該構(gòu)建注釋參數(shù)告訴go build只在編譯程序?qū)?yīng)的目標(biāo)操作系統(tǒng)是Linux或Mac OS X時(shí)才編譯這個(gè)文件。下面的構(gòu)建注釋則表示不編譯這個(gè)文件:

// +build ignore

更多細(xì)節(jié),可以參考go/build包的構(gòu)建約束部分的文檔。

$ go doc go/build

10.7.4. 包文檔

Go語言的編碼風(fēng)格鼓勵(lì)為每個(gè)包提供良好的文檔。包中每個(gè)導(dǎo)出的成員和包聲明前都應(yīng)該包含目的和用法說明的注釋。

Go語言中的文檔注釋一般是完整的句子,第一行通常是摘要說明,以被注釋者的名字開頭。注釋中函數(shù)的參數(shù)或其它的標(biāo)識(shí)符并不需要額外的引號(hào)或其它標(biāo)記注明。例如,下面是fmt.Fprintf的文檔注釋。

// Fprintf formats according to a format specifier and writes to w.
// It returns the number of bytes written and any write error encountered.
func Fprintf(w io.Writer, format string, a ...interface{}) (int, error)

Fprintf函數(shù)格式化的細(xì)節(jié)在fmt包文檔中描述。如果注釋后緊跟著包聲明語句,那注釋對(duì)應(yīng)整個(gè)包的文檔。包文檔對(duì)應(yīng)的注釋只能有一個(gè)(譯注:其實(shí)可以有多個(gè),它們會(huì)組合成一個(gè)包文檔注釋),包注釋可以出現(xiàn)在任何一個(gè)源文件中。如果包的注釋內(nèi)容比較長(zhǎng),一般會(huì)放到一個(gè)獨(dú)立的源文件中;fmt包注釋就有300行之多。這個(gè)專門用于保存包文檔的源文件通常叫doc.go。

好的文檔并不需要面面俱到,文檔本身應(yīng)該是簡(jiǎn)潔但不可忽略的。事實(shí)上,Go語言的風(fēng)格更喜歡簡(jiǎn)潔的文檔,并且文檔也是需要像代碼一樣維護(hù)的。對(duì)于一組聲明語句,可以用一個(gè)精煉的句子描述,如果是顯而易見的功能則并不需要注釋。

在本書中,只要空間允許,我們之前很多包聲明都包含了注釋文檔,但你可以從標(biāo)準(zhǔn)庫中發(fā)現(xiàn)很多更好的例子。有兩個(gè)工具可以幫到你。

首先是go doc命令,該命令打印其后所指定的實(shí)體的聲明與文檔注釋,該實(shí)體可能是一個(gè)包:

$ go doc time
package time // import "time"

Package time provides functionality for measuring and displaying time.

const Nanosecond Duration = 1 ...
func After(d Duration) <-chan Time
func Sleep(d Duration)
func Since(t Time) Duration
func Now() Time
type Duration int64
type Time struct { ... }
...many more...

或者是某個(gè)具體的包成員:

$ go doc time.Since
func Since(t Time) Duration

    Since returns the time elapsed since t.
    It is shorthand for time.Now().Sub(t).

或者是一個(gè)方法:

$ go doc time.Duration.Seconds
func (d Duration) Seconds() float64

    Seconds returns the duration as a floating-point number of seconds.

該命令并不需要輸入完整的包導(dǎo)入路徑或正確的大小寫。下面的命令將打印encoding/json包的(*json.Decoder).Decode方法的文檔:

$ go doc json.decode
func (dec *Decoder) Decode(v interface{}) error

    Decode reads the next JSON-encoded value from its input and stores
    it in the value pointed to by v.

第二個(gè)工具,名字也叫g(shù)odoc,它提供可以相互交叉引用的HTML頁面,但是包含和go doc命令相同以及更多的信息。圖10.1演示了time包的文檔,11.6節(jié)將看到godoc演示可以交互的示例程序。godoc的在線服務(wù) https://godoc.org ,包含了成千上萬的開源包的檢索工具。


你也可以在自己的工作區(qū)目錄運(yùn)行g(shù)odoc服務(wù)。運(yùn)行下面的命令,然后在瀏覽器查看 http://localhost:8000/pkg 頁面:

$ godoc -http :8000

其中-analysis=type-analysis=pointer命令行標(biāo)志參數(shù)用于打開文檔和代碼中關(guān)于靜態(tài)分析的結(jié)果。

10.7.5. 內(nèi)部包

在Go語言程序中,包是最重要的封裝機(jī)制。沒有導(dǎo)出的標(biāo)識(shí)符只在同一個(gè)包內(nèi)部可以訪問,而導(dǎo)出的標(biāo)識(shí)符則是面向全宇宙都是可見的。

有時(shí)候,一個(gè)中間的狀態(tài)可能也是有用的,標(biāo)識(shí)符對(duì)于一小部分信任的包是可見的,但并不是對(duì)所有調(diào)用者都可見。例如,當(dāng)我們計(jì)劃將一個(gè)大的包拆分為很多小的更容易維護(hù)的子包,但是我們并不想將內(nèi)部的子包結(jié)構(gòu)也完全暴露出去。同時(shí),我們可能還希望在內(nèi)部子包之間共享一些通用的處理包,或者我們只是想實(shí)驗(yàn)一個(gè)新包的還并不穩(wěn)定的接口,暫時(shí)只暴露給一些受限制的用戶使用。

為了滿足這些需求,Go語言的構(gòu)建工具對(duì)包含internal名字的路徑段的包導(dǎo)入路徑做了特殊處理。這種包叫internal包,一個(gè)internal包只能被和internal目錄有同一個(gè)父目錄的包所導(dǎo)入。例如,net/http/internal/chunked內(nèi)部包只能被net/http/httputil或net/http包導(dǎo)入,但是不能被net/url包導(dǎo)入。不過net/url包卻可以導(dǎo)入net/http/httputil包。

net/http
net/http/internal/chunked
net/http/httputil
net/url

10.7.6. 查詢包

go list命令可以查詢可用包的信息。其最簡(jiǎn)單的形式,可以測(cè)試包是否在工作區(qū)并打印它的導(dǎo)入路徑:

$ go list github.com/go-sql-driver/mysql
github.com/go-sql-driver/mysql

go list命令的參數(shù)還可以用"..."表示匹配任意的包的導(dǎo)入路徑。我們可以用它來列出工作區(qū)中的所有包:

$ go list ...
archive/tar
archive/zip
bufio
bytes
cmd/addr2line
cmd/api
...many more...

或者是特定子目錄下的所有包:

$ go list gopl.io/ch3/...
gopl.io/ch3/basename1
gopl.io/ch3/basename2
gopl.io/ch3/comma
gopl.io/ch3/mandelbrot
gopl.io/ch3/netflag
gopl.io/ch3/printints
gopl.io/ch3/surface

或者是和某個(gè)主題相關(guān)的所有包:

$ go list ...xml...
encoding/xml
gopl.io/ch7/xmlselect

go list命令還可以獲取每個(gè)包完整的元信息,而不僅僅只是導(dǎo)入路徑,這些元信息可以以不同格式提供給用戶。其中-json命令行參數(shù)表示用JSON格式打印每個(gè)包的元信息。

$ go list -json hash
{
    "Dir": "/home/gopher/go/src/hash",
    "ImportPath": "hash",
    "Name": "hash",
    "Doc": "Package hash provides interfaces for hash functions.",
    "Target": "/home/gopher/go/pkg/darwin_amd64/hash.a",
    "Goroot": true,
    "Standard": true,
    "Root": "/home/gopher/go",
    "GoFiles": [
            "hash.go"
    ],
    "Imports": [
        "io"
    ],
    "Deps": [
        "errors",
        "io",
        "runtime",
        "sync",
        "sync/atomic",
        "unsafe"
    ]
}

命令行參數(shù)-f則允許用戶使用text/template包(§4.6)的模板語言定義輸出文本的格式。下面的命令將打印strconv包的依賴的包,然后用join模板函數(shù)將結(jié)果鏈接為一行,連接時(shí)每個(gè)結(jié)果之間用一個(gè)空格分隔:

$ go list -f '{{join .Deps " "}}' strconv
errors math runtime unicode/utf8 unsafe

譯注:上面的命令在Windows的命令行運(yùn)行會(huì)遇到template: main:1: unclosed action的錯(cuò)誤。產(chǎn)生這個(gè)錯(cuò)誤的原因是因?yàn)槊钚袑?duì)命令中的" "參數(shù)進(jìn)行了轉(zhuǎn)義處理??梢园凑障旅娴姆椒ń鉀Q轉(zhuǎn)義字符串的問題:

$ go list -f "{{join .Deps \" \"}}" strconv

下面的命令打印compress子目錄下所有包的導(dǎo)入包列表:

$ go list -f '{{.ImportPath}} -> {{join .Imports " "}}' compress/...
compress/bzip2 -> bufio io sort
compress/flate -> bufio fmt io math sort strconv
compress/gzip -> bufio compress/flate errors fmt hash hash/crc32 io time
compress/lzw -> bufio errors fmt io
compress/zlib -> bufio compress/flate errors fmt hash hash/adler32 io

譯注:Windows下有同樣有問題,要避免轉(zhuǎn)義字符串的干擾:

$ go list -f "{{.ImportPath}} -> {{join .Imports \" \"}}" compress/...

go list命令對(duì)于一次性的交互式查詢或自動(dòng)化構(gòu)建或測(cè)試腳本都很有幫助。我們將在11.2.4節(jié)中再次使用它。每個(gè)子命令的更多信息,包括可設(shè)置的字段和意義,可以用go help list命令查看。

在本章,我們解釋了Go語言工具中除了測(cè)試命令之外的所有重要的子命令。在下一章,我們將看到如何用go test命令去運(yùn)行Go語言程序中的測(cè)試代碼。

練習(xí) 10.4: 創(chuàng)建一個(gè)工具,根據(jù)命令行指定的參數(shù),報(bào)告工作區(qū)所有依賴包指定的其它包集合。提示:你需要運(yùn)行go list命令兩次,一次用于初始化包,一次用于所有包。你可能需要用encoding/json(§4.5)包來分析輸出的JSON格式的信息。



以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)