### 10.7.2. 下載包

使用Go語言工具箱的go命令，不僅可以根據包導入路徑找到本地工作區的包，甚至可以從互聯網上找到和更新包。

使用命令`go get`可以下載一個單一的包或者用`...`下載整個子目録里面的每個包。Go語言工具箱的go命令同時計算併下載所依賴的每個包，這也是前一個例子中golang.org/x/net/html自動出現在本地工作區目録的原因。

一旦`go get`命令下載了包，然後就是安裝包或包對應的可執行的程序。我們將在下一節再關註它的細節，現在隻是展示整個下載過程是如何的簡單。第一個命令是獲取golint工具，它用於檢測Go源代碼的編程風格是否有問題。第二個命令是用golint命令對2.6.2節的gopl.io/ch2/popcount包代碼進行編碼風格檢査。它友好地報告了忘記了包的文檔：

```
$ 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`命令支持當前流行的託管網站GitHub、Bitbucket和Launchpad，可以直接向它們的版本控製繫統請求代碼。對於其它的網站，你可能需要指定版本控製繫統的具體路徑和協議，例如 Git或Mercurial。運行`go help importpath`獲取相關的信息。

`go get`命令獲取的代碼是眞實的本地存儲倉庫，而不僅僅隻是複製源文件，因此你依然可以使用版本管理工具比較本地代碼的變更或者切換到其它的版本。例如golang.org/x/net包目録對應一個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)
```

需要註意的是導入路徑含有的網站域名和本地Git倉庫對應遠程服務地址併不相同，眞實的Git地址是go.googlesource.com。這其實是Go語言工具的一個特性，可以讓包用一個自定義的導入路徑，但是眞實的代碼卻是由更通用的服務提供，例如googlesource.com或github.com。因爲頁面 https://golang.org/x/net/html 包含了如下的元數據，它告訴Go語言的工具當前包眞實的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`命令行標誌參數，`go get`命令將確保所有的包和依賴的包的版本都是最新的，然後重新編譯和安裝它們。如果不包含該標誌參數的話，而且如果包已經在本地存在，那麽代碼那麽將不會被自動更新。

`go get -u`命令隻是簡單地保證每個包是最新版本，如果是第一次下載包則是比較很方便的；但是對於發布程序則可能是不合適的，因爲本地程序可能需要對依賴的包做精確的版本依賴管理。通常的解決方案是使用vendor的目録用於存儲依賴包的固定版本的源代碼，對本地依賴的包的版本更新也是謹慎和持續可控的。在Go1.5之前，一般需要脩改包的導入路徑，所以複製後golang.org/x/net/html導入路徑可能會變爲gopl.io/vendor/golang.org/x/net/html。最新的Go語言命令已經支持vendor特性，但限於篇幅這里併不討論vendor的具體細節。不過可以通過`go help gopath`命令査看Vendor的幫助文檔。

**練習 10.3:** 從 http://gopl.io/ch1/helloworld?go-get=1 獲取內容，査看本書的代碼的眞實託管的網址（`go get`請求HTML頁面時包含了`go-get`參數，以區别普通的瀏覽器請求）。
