go 1.11.1
開始可以使用更優雅靈活的module
機制做包依賴管理,能直接感受到的優點如下:
- 項目路徑可以脫離
$GOPATH
了,不需要必須放在$GOPATH/src
下。 - 項目內部模塊的引入是基於
moduleName
而不再死板的基於projectName
了。 - 半自動維護依賴,如果你很懶,你甚至可以不需要使用
get
預先安裝依賴,module
在run test build
時會檢測未下載的依賴,並自動下載它們。
回想以前吧!$GOPATH/src/projectName
後,項目中各模塊互相引用的話都是基於projectName
(go 的包加載機制導致的,去 $GOROOT/src
和 $GOPATH/src
去尋址,所以projectName
也需要作爲包引入路徑的一部分),別人使用你的項目時也必須是projectName
,否則就得把項目內的所有projectName
改爲他們的項目名,不優雅極了。
而module
模式下,項目的包域是moduleName
,和projectName
無關,項目名稱怎樣都好,moduleName
會註冊到加載路徑中去。
雖然module
可以靈活到消除項目名
作爲項目模塊引入路徑的槽點,但如果後面要轉爲普通的vendor
模式的話,我們還是建議moduleName
同projetName
保持一致。
init
初始化項目爲module
模式:go mod init moduleName
# 不需要必須在 $GOPATH/src 下
mkdir go_mod_proj && cd go_mod_proj
go mod init app
# go: creating new go.mod: module app
# 會生成一個 go.mod 文件 查看內容如下
vi go.mod
module app
go 1.12
# module app 即定義了當前項目的包域
# 往常我們要引入 go_mod_proj 下的 test 包需要
# import "go_mod_proj/test"
# module 模式下則是 優雅的很 像 PHP 的命名空間映射一樣靈活
# import "app/test"
示例
tree .
.
├── go.mod
├── main.go
└── utils
└── msg.go
# go.mod
module app
go 1.12
# utils/msg.go
package utils
func Hello() {
println("hello go")
}
# main.go
package main
import (
"app/utils" // 注意項目模塊包的引入是以 moduleName 作爲包域的
)
func main() {
utils.Hello()
}
# go run main.go
自動維護
我們日常開發時需要某依賴包的話,都會使用 go get
下載後再運行,module
模式下因爲會自動的解析項目依賴,會自動的去下載那些未在本地的依賴包,刪除那些不再需要的依賴包。
tidy
tidy
主要用來手動維護項目的包依賴,會檢測項目當前的依賴,做相應的記錄或移除。
# 比如引入一個依賴包
package main
import (
"app/utils"
"github.com/sqrtcat/hello"
)
func main() {
utils.Hello()
hello.Hello()
}
# 運行一下
go mod tidy
# 查看 go.mod
module app
go 1.12
require github.com/sqrtcat/hello v0.0.0-20190617081741-06081a1a8fc1
# 刪掉 main.go 中 hello 包的引入後再執行
# main.go
package main
import (
"app/utils"
)
func main() {
utils.Hello()
}
# 運行一下
go mod tidy
# 查看 go.mod
module app
go 1.12
edit
不常用,忽略
vendor
將module
項目轉爲普通的vendor
項目,這時就需要將項目移至$GOPATH/src
下,並要保證projectName
同moduleName
保持一致,否則要手動去修改項目模塊包的加載路徑了。