為了解決go包管理的問題,go從1.11開始加入了go modules這一新特性。讓包的依賴和版本管理更加容易。
乙個module
可以理解為乙個單獨的包或者模組,module
的根目錄下會包含乙個go.mod
檔案。go.mod
檔案中定義了該module
被其它包import
的path
,同時也包含了該module
中依賴哪些包,和這些包的版本號。
go 1.11需要設定go111module來開啟module功能
go111module=on,會開啟使用module
go111module=auto預設值,會根據當前目前來決定是否開啟module。如果當前目錄在``gopath/src``之外且當前目錄有``go.mod``檔案或當前檔案在包含go.mod檔案的目錄下面
從go 1.13開始module被預設開啟
在非gopath/src
目錄下建立乙個空資料夾hello
,然後在資料夾下建立hello.go
檔案:
package hello
func hello() string
寫乙個單測檔案hello_test.go
:
package hello
import "testing"
func testhello(t *testing.t)
}
執行go test命令,這個時候返回:
ps d:\code\hello> go test
pass
ok _/d_/code/hello 0.176s
可以看到當前的目錄是在d:\code\hello
,不在gopath/src
目錄下,這時我們並沒有建立module,但是go在執行時創造了乙個假的module名稱是:_/d_/code/hello
接下來執行go mod init
命令,建立乙個module並且執行單測:
ok example.com/hello 0.177s可以看到case執行通過,並且返回ok example.com/hello 0.177s
就是是我們剛才建立的module。在目錄下面也可以看多了乙個go.mod
檔案它的內容是:
go 1.14mod
是在module
的根目錄下建立的,子目錄的import path
是module的path
加上子目錄的位址。
在hello.go檔案中匯入乙個外部的包:
package hello
import "rsc.io/quote"
func hello() string
執行單測:
go: finding module for package rsc.io/quote
go: found rsc.io/quote in rsc.io/quote v1.5.2
--- fail: testhello (0.00s)
hello_test.go:8: hello() = "你好,世界。", want "hello, world."
pass
ok example.com/hello 0.177s
這時開啟go.mod
檔案:
go 1.14
require rsc.io/quote v1.5.2可以發現go會自動去找rsc.io/quote
這個依賴的最新版本同時加入到go.mod
檔案中,再次執行單測:
pass
ok example.com/hello 0.177s
可以發現go
第二次已經不需要去找rsc.io/quote
。執行go list -m all
返回:
rsc.io/sampler v1.3.0可以看到引入外部依賴rsc.io/quote
,也會帶來它的間接依賴
除了go.mod
檔案,目錄中也會增加乙個go.sum
檔案內容如下:
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgoy6wgzoatkiimivjbqcw93erbe4m30ibm00nkl0i8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:nqm8euou14njkj3fqmw+pc6ldnwhi/ijpwht7yyuwoq=
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtd/ao+qwrjyzoknam9uh2b40telts3y=
rsc.io/quote v1.5.2/go.mod h1:lzx7hefjvl54yjefdedhnondjii0t9xzlpxsue+tkr0=
rsc.io/sampler v1.3.0 h1:7uvkifmebqhfdjd+gzwtxxi+rodj2wc4o7mpeh/qiw4=
rsc.io/sampler v1.3.0/go.mod h1:t1hpzkmbbmnahibkfy5hrxp6adajacjk9jxdnkatxpa=
通過上面的go list -m all
可以看到golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
我們用到的版本是v0.0.0-20170915032832-14c0d48ead0c
。我們接下來公升級它的版本:
go get golang.org/x/text
go: golang.org/x/text upgrade => v0.3.3
go: downloading golang.org/x/text v0.3.3
go test
pass
ok example.com/hello 0.199s
此時go.mod
檔案內容是:
go 1.14
require (
golang.org/x/text v0.3.3 // indirect
rsc.io/quote v1.5.2
)可以看到golang.org/x/text v0.3.3 // indirect
這個間接依賴已經被公升級到v0.3.3
了。
執行go list -m all
返回:
rsc.io/sampler v1.3.0執行go mod tidy
可以刪除沒有使用的包
開啟老專案的目錄一般是在gopath/src
下面,然後執行
go mod init ***
go build
需要注意的是遷移專案可能會出現包衝突的問題,會報類似
cannot load ***x: ambiguous import: found ***x in multiple modules:
這樣的錯誤,這時可能需要再go.mod中手動指定這個包的版本號 Go 語言程式設計 go mod 依賴包管理
golang 將 modules 模組 定義為 源 交付和版本控制的單元 有了 go mod 之後,每個專案 源 目錄 就是乙個 module,只要其中包含了 go.mod 檔案。go mod 指令和 go.mod 檔案用於記錄和解析模組之間的依賴性。go.mod 檔案一旦建立後,它的內容將會被 g...
3 Go mod及包管理
目錄 一 包的介紹和定義 二 包管理工具 go mod 1 go mod init 初始化專案 2 go mod 其他命令 三 自定義包 1 定義乙個包 2 匯入乙個包 四 使用第三方包 2 安裝這個包 包 package 是多個 go 原始碼的集合,是一種高階的 復用方案,go 語言為我們提供了很...
Go mod 之 Golang依賴包管理
如果你還在使用 gopath 模式來開發golang程式,那麼你可以參考本文來告別 gopath,並帶給你乙個方便的包管理工具。使用go mod 管理專案,就不需要非得把專案放到gopath指定目錄 直接使用命令 go mod init 目錄名稱 看到提示 go creating new go.mo...