前言
Go語言有超過100個的標準包,可以通過以下命令獲取標準包
go list std
也可以通過http://godoc.org檢索包。
模塊化設計成每個包可以被其它的不同項目共享和重用,在項目範圍內統一的分發和複用。每個包一般都定義了一個不同的名字空間,防止命名衝突。還通過控制包內名字的可見性和是否導出來實現封裝性,還可以強制用戶通過某些特定函數來訪問和更新內部變量,這樣可以保證內部變量的一致性和併發時的互斥約束。
當我們修改了一個源文件,我們必須重新編譯該源文件對應的包和所有依賴該包的其他包。可以併發編譯,有向無環圖遍歷+標記狀態,目標文件同時還記錄了包的依賴關係可以進行剪枝。
1. package聲明
每個Go語言源文件的開頭都必須有包聲明語句
package main
1.1 特殊包
- main包對應一個可執行程序,main包提示go build構建命令,這個包編譯完之後必須調用連接器生成一個可執行程序。
- 測試外部擴展包(
_test
爲後綴)由go test命令獨立編譯,避免測試代碼中的循環導入依賴,e.g. package memo_test - 版本包 導入路徑後追加版本號信息,e.g. gopkg.in/yaml.v2
2. import路徑
爲了避免衝突,所有非標準庫包的導入路徑建議以所在組織的互聯網域名爲前綴;而且這樣也有利於包的檢索。例如,下面的import語句導入了Go團隊維護的官方HTML解析器和一個流行的第三方維護的MySQL驅動。gofmt和goimports工具有助於自動導入、排序和格式排版。
import (
"fmt" // 標準包
"math/rand"
"golang.org/x/net/html" // 官方擴展包
"github.com/go-sql-driver/mysql" // github第三方包
)
默認的包名就是包導入路徑名的最後一段,因此即使兩個包的導入路徑不同,它們依然可能有一個相同的包名。例如math/rand包和crypto/rand包,那麼導入聲明必須至少爲一個同名包指定一個別名以避免衝突。這叫做導入包的重命名。
import (
"crypto/rand"
mrand "math/rand" // 別名
)
別名不僅僅只是爲了解決名字衝突,也可以縮短笨重的包名,引用更方便。 每個導入聲明語句都明確指定了當前包和被導入包之間的依賴關係。如果遇到包循環導入的情況,Go語言的構建工具將報告錯誤。
2.1 匿名導入
如果只是導入一個包而並不使用導入的包將會導致一個編譯錯誤。
有時候我們只是想利用導入包而產生的副作用:它會計算包級變量的初始化表達式和執行導入包的init初始化函數。這時候我們需要抑制“unused import”編譯錯誤,我們可以用下劃線_
來重命名導入的包。
import _ "image/png" // 副作用註冊PNG 解碼器
import (
"database/sql"
_ "github.com/lib/pq" // 第三方數據庫驅動enable support for Postgres
_ "github.com/go-sql-driver/mysql" // enable support for MySQL
)
3.包命名規範
- 包名一般採用單數的形式。
- 要避免包名有其它的含義。
- 考慮包名和成員名兩個部分如何很好地配合,如http.Get
4.工具
go工具 | 解釋 |
---|---|
go env |
Go語言工具涉及的所有環境變量的值 |
go get |
下載一個單一的包或者用
clone整個倉庫
|
go build |
編譯命令行參數指定的每個包。 如果包名是main,將調用鏈接器在當前目錄創建一個可執行程序;以導入路徑的最後一段作爲可執行程序的名字。 如果沒有指定參數,那麼默認指定爲當前目錄對應的包
|
go install | 類似於build,只是會保存每個包的編譯成果到$GOPATH/pkg |
go doc |
構建doc文檔 所有導出成員註釋 |
go list |
查詢可用包的信息
|
go test | 運行Go語言程序中的測試代碼 |