Go 1.11和1.12實現了對包管理的初步支持,Go的新依賴管理系統使依賴版本信息明確且易於管理。
Using Go Modules - The Go Bloggit
做爲Go語言的推廣者,經常被問到各類關於Go語言的基礎特性問題。
其中,關於包管理方面的問題會讓我很是尷尬,由於Go的包管理在1.11以前與Python、Node、Java比較起來真的只能算是「僅僅可用」而已。github
由於:golang
$GOPATH/src
下的依賴包新的包管理模式解決了以上問題shell
GO111MODULE=auto
準備完畢,很是簡單吧!!工具
首先,在$GOPATH/src
路徑外的你喜歡的地方建立一個目錄,cd 進入目錄,新建一個hello.go文件,內容以下學習
package main import ( "fmt" ) func main() { fmt.Println("Hello, world!") }
在當前目錄下,命令行運行 go mod init + 模塊名稱 初始化模塊ui
go mod init hello
運行完後,會在當前項目目錄下生成一個go.mod 文件,這是一個關鍵文件,以後的包的管理都是經過這個文件管理。加密
官方說明:除了go.mod以外,go命令還維護一個名爲go.sum的文件,其中包含特定模塊版本內容的預期加密哈希
go命令使用go.sum文件確保這些模塊的將來下載檢索與第一次下載相同的位,以確保項目所依賴的模塊不會出現意外更改,不管是出於惡意、意外仍是其餘緣由。 go.mod和go.sum都應檢入版本控制。
go.sum 不須要手工維護,因此能夠不用太關注。
生成出來的文件包含模塊名稱和當前的go版本號spa
module hello go 1.12
注意:子目錄裏是不須要init的,全部的子目錄裏的依賴都會組織在根目錄的go.mod文件裏命令行
接下來,讓你的項目依賴一下第三方包
以大部分人都熟悉的beego爲例吧!
修改Hello.go文件:
package main import "github.com/astaxie/beego" func main() { beego.Run() }
按照過去的作法,要運行hello.go須要執行go get
命令 下載beego包到 $GOPATH/src
可是,使用了新的包管理就不在須要這樣作了
直接 go run hello.go
稍等片刻… go 會自動查找代碼中的包,下載依賴包,而且把具體的依賴關係和版本寫入到go.mod和go.sum文件中。
查看go.mod,它會變成這樣:
module hello go 1.12 require github.com/astaxie/beego v1.11.1
require
關鍵子是引用,後面是包,最後v1.11.1 是引用的版本號
這樣,一個使用Go包管理方式建立項目的小例子就完成了。
那麼,接下來,幾個小問題來了
不在。
使用Go的包管理方式,依賴的第三方包被下載到了$GOPATH/pkg/mod
路徑下。
若是你成功運行了本例,能夠在您的$GOPATH/pkg/mod
下找到一個這樣的包 github.com/astaxie/beego@v1.11.1
在上一個問題裏,能夠看到最終下載在$GOPATH/pkg/mod
下的包 github.com/astaxie/beego@v1.11.1
最後會有一個版本號 1.11.1,也就是說,$GOPATH/pkg/mod
裏能夠保存相同包的不一樣版本。
版本是在go.mod中指定的。
若是,在go.mod中沒有指定,go命令會自動下載代碼中的依賴的最新版本,本例就是自動下載最新的版本。
若是,在go.mod用require語句指定包和版本 ,go命令會根據指定的路徑和版本下載包,
指定版本時能夠用latest
,這樣它會自動下載指定包的最新版本;
依賴包的版本號是什麼? 是包的發佈者標記的版本號,格式爲 vn.n.n (n表明數字),本例中的beego的歷史版本能夠在其代碼倉庫release看到Releases · astaxie/beego · GitHub
若是包的做者尚未標記版本,默認爲 v0.0.0
能夠。
可是go會根據GO111MODULE的值而採起不一樣的處理方式
默認狀況下,GO111MODULE=auto
自動模式
$GOPATH/src
裏會使用$GOPATH/src
的依賴包,在$GOPATH/src外,就使用go.mod 裏 require的包$GOPATH/src
裏仍是在外面,都會使用go.mod 裏 require的包在go快速發展的過程當中,有一些依賴包地址變動了。
之前的作法
不管什麼方法,都不便於維護,特別是多人協同開發時。
使用go.mod就簡單了,在go.mod文件裏用 replace 替換包,例如
replace golang.org/x/text => github.com/golang/text latest
這樣,go會用 github.com/golang/text 替代golang.org/x/text,原理就是下載github.com/golang/text 的最新版本到 $GOPATH/pkg/mod/golang.org/x/text
下。
本例裏,用 go mod init hello 生成的go.mod文件裏的第一行會申明module hello
由於咱們的項目已經不在$GOPATH/src
裏了,那麼引用本身怎麼辦?就用模塊名+路徑。
例如,在項目下新建目錄 utils,建立一個tools.go文件:
package utils import 「fmt」 func PrintText(text string) { fmt.Println(text) }
在根目錄下的hello.go文件就能夠 import 「hello/utils」 引用utils
package main import ( "hello/utils" "github.com/astaxie/beego" ) func main() { utils.PrintText("Hi") beego.Run() }
$GOPATH/src
外go mod init + 模塊名稱
go build
或者 go run
一次關於Go 1.12的包管理介紹大體就到此了
根據官方的說法,從Go 1.13開始,模塊管理模式將是Go語言開發的默認模式。
因此,Pick起來吧!
有問題或者須要討論的朋友,能夠給我留言,共同窗習,一塊兒進步