任何包系統設計的目的都是爲了簡化大型程序的設計和維護工做,經過將一組相關的特性放進一個獨立的單元以便於理解和更新,在每一個單元更新的同時保持和程序中其它單元的相對獨立性。這種模塊化的特性容許每一個包能夠被其它的不一樣項目共享和重用,在項目範圍內、甚至全球範圍統一的分發和複用。html
每一個包通常都定義了一個不一樣的名字空間用於它內部的每一個標識符的訪問。每一個名字空間關聯到一個特定的包,讓咱們給類型、函數等選擇簡短明瞭的名字,這樣能夠在使用它們的時候減小和其它部分名字的衝突。python
每一個包還經過控制包內名字的可見性和是否導出來實現封裝特性。經過限制包成員的可見性並隱藏包API的具體實現,將容許包的維護者在不影響外部包用戶的前提下調整包的內部實現。經過限制包內變量的可見性,還能夠強制用戶經過某些特定函數來訪問和更新內部變量,這樣能夠保證內部變量的一致性和併發時的互斥約束。mysql
每一個包是由一個全局惟一的字符串所標識的導入路徑定位。出如今import語句中的導入路徑也是字符串。git
import ( "fmt" "math/rand" "encoding/json" "golang.org/x/net/html" "github.com/go-sql-driver/mysql" )
在每一個Go語言源文件的開頭都必須有包聲明語句。包聲明語句的主要目的是肯定當前包被其它包導入時默認的標識符(也稱爲包名)。github
一般來講,默認的包名就是包導入路徑名的最後一段,所以即便兩個包的導入路徑不一樣,它們依然可能有一個相同的包名。例如,math/rand
包和golang.org/x/exp/rand
包的包名都是rand
。golang
package main import ( "fmt" "math/rand" ) // 導入rand包 用rand包裏的方法函數等 func main() { fmt.Println(rand.Int63n(10000)) // 9410 }
package main import ( "fmt" "golang.org/x/exp/rand" ) func main() { fmt.Println(rand.Int63n(10000)) // 9351 }
若是咱們想同時導入兩個有着名字相同的包,例如math/rand
包和golang.org/x/exp/rand
包,那麼導入聲明必須至少爲一個同名包指定一個新的包名以免衝突。這叫作導入包的重命名。sql
package main import ( "fmt" rand1 "math/rand" rand2 "golang.org/x/exp/rand" ) func main() { fmt.Println(rand1.Int63n(10000)) // 9401 fmt.Println(rand2.Int63n(10000)) // 9351 }
若是隻是導入一個包而並不使用導入的包將會致使一個編譯錯誤。可是有時候咱們只是想利用導入包而產生的反作用:它會計算包級變量的初始化表達式和執行導入包的init初始化函數。這時候咱們須要抑制「unused import」編譯錯誤,咱們能夠用下劃線_
來重命名導入的包。好比序號gorm
包是要帶入sql驅動json
import ( "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) func main() { db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local") defer db.Close() }
當建立一個包,通常要用短小的包名,但也不能過短致使難以理解。標準庫中最經常使用的包有bufio
、bytes
、flag
、fmt
、http
、io
、json
、os
、sort
、sync
和time
等包。session
包名通常採用單數的形式。標準庫的bytes、errors和strings使用了複數形式,這是爲了不和預約義的類型衝突,一樣還有go/types是爲了不和type關鍵字衝突。併發
Go語言工具箱的具體功能,包括如何下載、格式化、構建、測試和安裝Go語言編寫的程序。
$ 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. ...
使用Go語言工具箱的go命令,不只能夠根據包導入路徑找到本地工做區的包,甚至能夠從互聯網上找到和更新包。
使用命令go get
能夠下載一個單一的包或者用...
下載整個子目錄裏面的每一個包。Go語言工具箱的go命令同時計算並下載所依賴的每一個包,這也是前一個例子中golang.org/x/net/html
自動出如今本地工做區目錄的緣由。
go build
命令編譯命令行參數指定的每一個包。若是包是一個庫,則忽略輸出結果;這能夠用於檢測包是能夠正確編譯的。若是包的名字是main,go build
將調用連接器在當前目錄建立一個可執行程序;以導入路徑的最後一段做爲可執行程序的名字。
Go語言的編碼風格鼓勵爲每一個包提供良好的文檔。包中每一個導出的成員和包聲明前都應該包含目的和用法說明的註釋。
Go語言中的文檔註釋通常是完整的句子,第一行一般是摘要說明,以被註釋者的名字開頭。註釋中函數的參數或其它的標識符並不須要額外的引號或其它標記註明。例如,下面是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)
首先是go doc
命令,該命令打印其後所指定的實體的聲明與文檔註釋,該實體多是一個包:
$ 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...
或者是某個具體的包成員:
$ go doc time.Since func Since(t Time) Duration Since returns the time elapsed since t. It is shorthand for time.Now().Sub(t).
或者是一個方法:
$ go doc time.Duration.Seconds func (d Duration) Seconds() float64 Seconds returns the duration as a floating-point number of seconds.
在Go語言程序中,包是最重要的封裝機制。沒有導出的標識符只在同一個包內部能夠訪問,而導出的標識符則是面向全宇宙都是可見的。
net/http net/http/internal/chunked net/http/httputil net/url
go list
命令能夠查詢可用包的信息。其最簡單的形式,能夠測試包是否在工做區並打印它的導入路徑:
$ go list github.com/go-sql-driver/mysql github.com/go-sql-driver/mysql
go list
命令還能夠獲取每一個包完整的元信息,而不只僅只是導入路徑,這些元信息能夠以不一樣格式提供給用戶。其中-json
命令行參數表示用JSON格式打印每一個包的元信息。能夠用"..."
表示匹配相關包的包的導入路徑。
$ go list ...mysql github.com/astaxie/beego/session/mysql github.com/go-sql-driver/mysql
參考文章: